线程同步之互斥量加锁解锁 死锁
與互斥鎖相關(guān)API
??????互斥量(mutex)從本質(zhì)上來(lái)說(shuō)是一把鎖,在訪問(wèn)共享資源前對(duì)互斥量進(jìn)行加鎖,在訪問(wèn)完成后釋放互斥量上的鎖。對(duì)互斥量進(jìn)行加鎖后,任何其他試圖再次對(duì)互斥量加鎖的線程將會(huì)被阻塞直到當(dāng)前線程釋放該互斥鎖。如果釋放互斥鎖時(shí)有多個(gè)線程阻塞,所有在該互斥鎖上的阻塞線程都會(huì)變成可運(yùn)行狀態(tài),第一個(gè)變?yōu)榭蛇\(yùn)行狀態(tài)的線程可以對(duì)互斥量加鎖,其他線程將會(huì)看到互斥鎖依然被鎖住,只能回去等待它重新變?yōu)榭捎谩T谶@種方式下,每次只有一個(gè)線程可以向前運(yùn)行。
??????在設(shè)計(jì)時(shí)需要規(guī)定所有的線程必須遵守相同的數(shù)據(jù)訪問(wèn)規(guī)則。只有這樣,互斥機(jī)制才能正常工作。操作系統(tǒng)并不會(huì)做數(shù)據(jù)訪問(wèn)的串行化。如果允許其中的某個(gè)線程在沒(méi)有得到鎖的情況下也可以訪問(wèn)共享資源,那么即使其它的線程在使用共享資源前都獲取了鎖,也還是會(huì)出現(xiàn)數(shù)據(jù)不一致的問(wèn)題。
??????互斥變量用pthread_mutex_t數(shù)據(jù)類(lèi)型表示。在使用互斥變量前必須對(duì)它進(jìn)行初始化,可以把它置為常量PTHREAD_MUTEX_INITIALIZER(只對(duì)靜態(tài)分配的互斥量),也可以通過(guò)調(diào)用pthread_mutex_init函數(shù)進(jìn)行初始化。如果動(dòng)態(tài)地分配互斥量(例如通過(guò)調(diào)用malloc函數(shù)),那么在釋放內(nèi)存前需要調(diào)用pthread_mutex_destroy。
1. 創(chuàng)建及銷(xiāo)毀互斥鎖
要用默認(rèn)的屬性初始化互斥量,只需把a(bǔ)ttr設(shè)置為NULL。
2. 加鎖及解鎖
??????如果線程不希望被阻塞,它可以使用pthread_mutex_trylock嘗試對(duì)互斥量進(jìn)行加鎖。如果調(diào)用pthread_mutex_trylock時(shí)互斥量處于未鎖住狀態(tài),那么pthread_mutex_trylock將鎖住互斥量,不會(huì)出現(xiàn)阻塞并返回0,否則pthread_mutex_trylock就會(huì)失敗,不能鎖住互斥量,而返回EBUSY。
代碼示例
#include<stdio.h> #include<pthread.h> //int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);int g_data=0; pthread_mutex_t mutex;//定義一個(gè)互斥量也就是鎖void*func1(void *arg) {int i;pthread_mutex_lock(&mutex);//給互斥量上鎖for(i=0;i<5;i++){printf("t1 :%ld thread is created\n",(unsigned long)pthread_self());printf("t1:param is %d\n",*((int*)arg));}pthread_mutex_unlock(&mutex);//給互斥量解鎖}void*func2(void *arg) {pthread_mutex_lock(&mutex);//給互斥量上鎖printf("t2 :%ld thread is created\n",(unsigned long)pthread_self());printf("t2:param is %d\n",*((int*)arg));pthread_mutex_unlock(&mutex);//給互斥量解鎖}int main() {int ret;int param=100;pthread_t t1;pthread_t t2;pthread_mutex_init(&mutex,NULL);//初始化互斥量ret=pthread_create(&t1,NULL,func1,(void*)¶m);if(ret==0){printf("main:create t1 success\n");}ret=pthread_create(&t2,NULL,func2,(void*)¶m);if(ret==0){printf("main:create t2 success\n");}printf("main : %ld \n",(unsigned long)pthread_self());pthread_join(t1,NULL);//用來(lái)等待進(jìn)程t1退出pthread_join(t2,NULL);//用來(lái)等待進(jìn)程t2退出pthread_mutex_destroy(&mutex);//銷(xiāo)毀這把鎖return 0; }腳本可以這樣寫(xiě)
CLC@Embed_Learn:~/xiancheng$ vi test.sh CLC@Embed_Learn:~/xiancheng$ chmod +x test.sh CLC@Embed_Learn:~/xiancheng$ ./test.sh //其中test.sh中寫(xiě)入要運(yùn)行的程序實(shí)現(xiàn)進(jìn)程t1滿足條件退出代碼
#include<stdio.h> #include<pthread.h> #include <stdlib.h> //int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);int g_data=0;//pthread_mutex_t mutex;void*func1(void *arg) {printf("t1 :%ld thread is created\n",(unsigned long)pthread_self());printf("t1:param is %d\n",*((int*)arg));pthread_mutex_lock(&mutex);while(1){printf("t1 printf is %d\n",g_data++);sleep(1);if(g_data==3){pthread_mutex_unlock(&mutex);printf("t1 over==============================\n");//pthread_exit(NULL);exit(0);}}}void*func2(void *arg) {printf("t2 :%ld thread is created\n",(unsigned long)pthread_self());printf("t2:param is %d\n",*((int*)arg));while(1){printf("t2 printf is %d\n",g_data);pthread_mutex_lock(&mutex);g_data++; pthread_mutex_unlock(&mutex);sleep(1);}pthread_mutex_unlock(&mutex); }int main() {int ret;int param=100;pthread_t t1;pthread_t t2;pthread_mutex_init(&mutex,NULL);ret=pthread_create(&t1,NULL,func1,(void*)¶m);if(ret==0){printf("main:create t1 success\n");}ret=pthread_create(&t2,NULL,func2,(void*)¶m);if(ret==0){printf("main:create t2 success\n");}printf("main : %ld \n",(unsigned long)pthread_self());while(1){printf("main printf is %d\n",g_data);sleep(1);}pthread_join(t1,NULL);pthread_join(t2,NULL);pthread_mutex_destory(&mutex);return 0; }什么情況下造成死鎖
??????死鎖 是指兩個(gè)或兩個(gè)以上的進(jìn)程在執(zhí)行過(guò)程中,由于競(jìng)爭(zhēng)資源或彼此通信而造成的一種阻塞現(xiàn)象,無(wú)外力作用,他們都將無(wú)法再推進(jìn)下去。(一般需要兩個(gè)mutex)
代碼示例
參考博文:https://www.cnblogs.com/xiehongfeng100/p/4620852.html
總結(jié)
以上是生活随笔為你收集整理的线程同步之互斥量加锁解锁 死锁的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java学习(120):set的iter
- 下一篇: html:(39):块级元素和内联块级元