Sistem Linux ialah sistem pengendalian yang menyokong pelaksanaan serentak pelbagai tugas Ia boleh menjalankan berbilang proses pada masa yang sama, dengan itu meningkatkan penggunaan dan kecekapan sistem. Walau bagaimanapun, jika terdapat berbilang utas dalam proses, dan utas ini perlu berkongsi beberapa data atau sumber, ketidakkonsistenan data atau persaingan sumber mungkin berlaku, yang membawa kepada ralat atau pengecualian sistem. Untuk menyelesaikan masalah ini, anda perlu menggunakan beberapa mekanisme penyegerakan, seperti semaphore, pembolehubah keadaan, mutex, dll. Antaranya, mutex ialah mekanisme penyegerakan yang agak mudah dan berkesan Ia membenarkan benang mengunci data atau sumber yang dikongsi apabila mengaksesnya untuk menghalang utas lain daripada mengaksesnya pada masa yang sama, sekali gus memastikan keselamatan benang. Artikel ini akan menerangkan secara terperinci kaedah menyegerakkan mutex Mutex dalam berbilang benang Linux, termasuk pemulaan, penguncian, buka kunci dan pemusnahan mutex.
Di bawah Linux, jenis data mutex thread ialah pthread_mutex_t Sebelum digunakan, ia mesti dimulakan:
Untuk mutex yang diperuntukkan secara statik, anda boleh menetapkannya kepada PTHREAD_MUTEX_INITIALIZER, atau hubungi pthread_mutex_init.
Untuk mutex yang diperuntukkan secara dinamik, selepas memohon memori (malloc), ia dimulakan melalui pthread_mutex_init, dan pthread_mutex_destroy perlu dipanggil sebelum melepaskan memori (percuma).
Prototaip:
int pthread_mutex_init(pthread_mutex_t *sekat mutex, const pthread_mutexattr_t *sekat attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
Fail pengepala:
Nilai pulangan: 0 jika berjaya, nombor ralat jika ralat berlaku.
Nota: Jika anda menggunakan atribut lalai untuk memulakan mutex, hanya tetapkan attr kepada NULL Nilai lain akan diterangkan kemudian.
Untuk mengakses sumber kongsi, anda perlu mengunci mutex Jika mutex sudah dikunci, utas panggilan akan disekat sehingga mutex dibuka kunci Selepas melengkapkan akses kepada sumber yang dikongsi, anda perlu mengunci mutex untuk membuka kunci .
Mari kita bercakap tentang fungsi penguncian:
Fail pengepala:
Prototaip:
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
Nilai pulangan: 0 jika berjaya, nombor ralat jika ralat berlaku.
Penjelasan: Mari kita bercakap tentang fungsi trylock secara khusus Fungsi ini ialah mod panggilan tidak menyekat, iaitu jika mutex tidak dikunci, fungsi trylock akan mengunci mutex dan mendapat akses kepada sumber yang dikongsi mutex tidak dikunci, fungsi trylock akan mengunci mutex dan mendapat akses kepada sumber yang dikongsi Eksklusif dikunci, dan fungsi trylock tidak akan menyekat dan menunggu tetapi akan terus mengembalikan EBUSY, menunjukkan bahawa sumber yang dikongsi sedang sibuk.
Mari kita bercakap tentang fungsi penyelesaian sekali lagi:Fail pengepala:
Prototaip: int pthread_mutex_unlock(pthread_mutex_t *mutex
Nilai pulangan: Mengembalikan 0 jika berjaya, mengembalikan nombor ralat jika ralat berlaku.
3. Kebuntuan:
Kebuntuan berlaku terutamanya apabila terdapat berbilang kunci bergantung, dan akan berlaku apabila satu utas cuba mengunci mutex dalam susunan yang bertentangan sebagai satu lagi benang Cara mengelakkan kebuntuan adalah sesuatu yang perlu diberi perhatian khusus apabila menggunakan mutex.
Secara umumnya, terdapat beberapa prinsip asas tidak bertulis:
Pastikan mendapatkan kunci sebelum mengendalikan sumber yang dikongsi.
Pastikan lepaskan kunci selepas selesai operasi.
Jika terdapat berbilang kunci, jika susunan pemerolehan adalah ABC, susunan pelepasan juga hendaklah ABC.
Benang harus melepaskan kunci yang diperolehnya apabila ia mengembalikan ralat.
Contoh:
#include #include #include #include #include pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; int lock_var; time_t end_time; int sum; void pthread1(void *arg); void pthread2(void *arg); void pthread3(void *arg); int main(int argc, char *argv[]) { pthread_t id1,id2,id3; pthread_t mon_th_id; int ret; sum=10; end_time = time(NULL) 10; pthread_mutex_init(&mutex,NULL); ret=pthread_create(&id1,NULL,(void *)pthread1, NULL); if(ret!=0) perror("pthread cread1"); ret=pthread_create(&id2,NULL,(void *)pthread2, NULL); if(ret!=0) perror("pthread cread2"); ret=pthread_create(&id3,NULL,(void *)pthread3, NULL); if(ret!=0) perror("pthread cread3"); pthread_join(id1,NULL); pthread_join(id2,NULL); pthread_join(id3,NULL); exit(0); } void pthread1(void *arg) { int i; while(time(NULL) if(pthread_mutex_lock(&mutex)!=0) //lock { perror("pthread_mutex_lock"); } else printf("pthread1:pthread1 lock the variablen"); for(i=0;iif(pthread_mutex_unlock(&mutex)!=0) //unlock { perror("pthread_mutex_unlock"); } else printf("pthread1:pthread1 unlock the variablen"); sleep(1); } } void pthread2(void *arg) { int nolock=0; int ret; while(time(NULL) if(ret==EBUSY) printf("pthread2:the variable is locked by pthread1n"); else{ if(ret!=0) { perror("pthread_mutex_trylock"); exit(1); } else printf("pthread2:pthread2 got lock.The variable is %dn",lock_var); if(pthread_mutex_unlock(&mutex)!=0)//unlock { perror("pthread_mutex_unlock"); } else printf("pthread2:pthread2 unlock the variablen"); } sleep(1); } } void pthread3(void *arg) {/* int nolock=0; int ret; while(time(NULL) if(ret==EBUSY) printf("pthread3:the variable is locked by pthread1 or 2n"); else { if(ret!=0) { perror("pthread_mutex_trylock"); exit(1); } else printf("pthread3:pthread3 got lock.The variable is %dn",lock_var); if(pthread_mutex_unlock(&mutex)!=0) { perror("pthread_mutex_unlock"); } else printf("pthread3:pthread2 unlock the variablen"); } sleep(3); }*/ }
Atas ialah kandungan terperinci Penjelasan terperinci tentang penyegerakan berbilang benang Linux mutex Mutex. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!