執行緒互斥和同步-- 互斥鎖
阿新 • • 發佈:2019-02-20
一. 執行緒分離
我們一般建立的執行緒是可結合的,這個時候如果我們呼叫pthread_jion()去等待的話,這種等待的方式是阻塞式等待,如果主執行緒一直等待,主執行緒就無法做其他的事情了,所以應該使用執行緒分離,讓子執行緒由作業系統回收,主執行緒就不管了。
不管執行緒是否分離,它始終是在程序的內部執行的。
使用的函式介面是pthread_detach(pthread_t pid)
如果分離自己引數為pthread_self(),如果是主執行緒分離子執行緒,引數為pthread_id
二. 執行緒互斥
因為我們的多個執行緒是共享一個資源的,這個資源就是臨界資源,多個執行緒對資源的訪問就需要使用執行緒的同步和互斥
互斥,對資源的訪問時序列的,原子的。即是,每次只能有一個執行緒訪問臨界 資源 。
三.執行緒同步
如果我們的某一個執行緒的優先順序特別高,那麼它可能會一直佔據這這臨界資源,這個時候,其他的執行緒就無法使用這個臨界資源,雖然我們實現了執行緒的互斥,但是隻有一個執行緒 使用它,這也是不符合我們的實際需求的,所以這個時候需要使用執行緒的同步。
執行緒同步的意思就是說,每次使用完一個臨界資源之後,都需要排隊,打個形象的比喻就是,如果我們一個人進入一個單獨自習室自習之後,出來的時候,必須排在其他的排在門口的人後面,不能直接出來又進去,這樣的話,他就是一直佔據著臨界資源了。
四. 互斥鎖
設定一個互斥鎖,這個時候一次,建立一個全域性的互斥鎖。
線上程函式裡面,每次一個執行緒 訪問的臨界資源的時候,首先要做的是就是獲取這個鎖,只有拿到鎖之後才能對臨界資源進行操作,然後每次在退出臨界資源之前,要解鎖,這樣其他的執行緒進入的時候才不會永遠拿不到鎖。
整個函式結束前,要銷燬鎖。
對於互斥鎖的一個深層次的理解
1. 互斥鎖本身就是一個臨界資源,所以對互斥鎖的操作本身就是原子的。
2. 每次線上程 函式的內部,每次需要申請鎖資源,如果申請失敗,當前的執行緒就會被掛起,掛起就是該執行緒的PCB在等待佇列裡面。
死鎖產生的情景
1. 多執行緒可能有多把鎖,這個時候,如果其中的某些執行緒 都想要訪問彼此的鎖,這個時候可能 都拿不到,然後就產生了死鎖。
2. 一個程序一把鎖,可能由於程式碼錯誤,當它申請鎖之後,已經 拿到了這把鎖,然後他又去申請同樣 的,這個時候就出現了死鎖。
下面看程式碼的實現。
#include<stdio.h> #include<pthread.h> int count = 0; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; //建立一把鎖,使用巨集進行初始化 void* pccount(void* arg) { int i = 0; int temp = 0; while(i<50000000) { pthread_mutex_lock(&lock); //加鎖,如果鎖資源是空,就拿到鎖,如果鎖資源不是空,就掛起等待 // temp=count; count=count+1; //printf("%d",temp); i++; pthread_mutex_unlock(&lock); //操作完臨界資源之後,要解鎖,這樣其他的執行緒才能夠獲取鎖資源 } // printf("%d\n",count); pthread_exit((void*)123); } int main() { pthread_t pid1; pthread_t pid2; int i = pthread_create(&pid1,NULL,pccount,NULL); int m = pthread_create(&pid2,NULL,pccount,NULL); void* join1; void* join2; pthread_join(pid1,&join1); pthread_join(pid2,&join2); //這裡必須要有執行緒等待,不然沒有列印結果 pthread_mutex_destroy(&lock); //銷燬鎖資源 printf("%d\n",count); return 0; }