之前的文章已經回顧了多執行緒同步的6種方式,這裡就互斥鎖和條件變數的配合使用,以及關卡的使用舉個栗子。
以牛客網上迅雷的一道面試題為例。
1. 題目
編寫乙個程式,開啟3個執行緒,這3個執行緒的id分別為a、b、c。
每個執行緒將自己的id在螢幕上列印10遍,要求輸出結果必須按abc的順序顯示;如:abcabc….依次遞推。
2. 實現思路
3. 一些執行緒函式原型
4. **實現- 使用pthread_join()
#include
#include
#include
pthread_t a, b, c; //執行緒id
pthread_mutex_t lock = pthread_mutex_initializer; //互斥鎖,條件變數對資源的互斥訪問
pthread_cond_t condition = pthread_cond_initializer; //條件變數
int flag = 0; //把執行緒阻塞在條件變數的條件,全域性變數
void *printthread1(void *arg);
void *printthread2(void *arg);
void *printthread3(void *arg);
int main()
//條件置位讓執行緒1開始執行
flag = 1;
if ((res = pthread_create(&b, null, printthread2, null)) != 0)
if ((res = pthread_create(&c, null, printthread3, null)) != 0)
//等待各個子執行緒結束
pthread_join(a, null);
pthread_join(b, null);
pthread_join(c, null);
//釋放記憶體之前銷毀互斥鎖和條件變數
pthread_mutex_destroy(&lock);
pthread_cond_destroy(&condition);
return0;}
void *printthread1(void *arg)
return
null; //或return ((void *)0);
}void *printthread2(void *arg)
return
null;
}void *printthread3(void *arg)
return
null;
}
說明:[1] 互斥鎖和條件變數靜態建立,因此可以選擇靜態初始化(賦值)或者動態初始化(函式)的方式
[2] 之前將條件置位語句flag = 1放在了建立完執行緒之後,發現有的時候能正常執行輸出,有的時候又完全沒有反應。問題在於執行緒建立之後,執行哪乙個是隨機的,如果不是執行緒1條件在等待,則不會繼續執行。
[3] pthread_join()對不同函式的等待沒有先後順序,所以pthread_join(a, null),pthread_join(b, null),pthread_join(c, null)誰在前誰在後都沒有關係。
[4] int i, j, k的定義放到了各個執行緒中而不是作為全域性變數,因為執行緒執行起來後直至執行結束才會退出,因此可作為區域性變數。
4. **實現- 使用關卡barriers
#include
#include
#include
pthread_t a, b, c; //執行緒id
pthread_mutex_t lock = pthread_mutex_initializer; //互斥鎖,條件變數對資源的互斥訪問
pthread_cond_t condition = pthread_cond_initializer; //條件變數
pthread_barrier_t barrier; //關卡
int flag = 0; //把執行緒阻塞在條件變數的條件,全域性變數
void *printthread1(void *arg);
void *printthread2(void *arg);
void *printthread3(void *arg);
int main()
//條件置位讓執行緒1開始執行
flag = 1;
if ((res = pthread_create(&b, null, printthread2, null)) != 0)
if ((res = pthread_create(&c, null, printthread3, null)) != 0)
//設定執行緒關卡,每個執行緒執行到關卡均等待
pthread_barrier_wait(&barrier);
//釋放記憶體之前銷毀互斥鎖和條件變數
pthread_mutex_destroy(&lock);
pthread_cond_destroy(&condition);
pthread_barrier_destroy(&barrier);
return0;}
void *printthread1(void *arg)
pthread_barrier_wait(&barrier);
return null;
}void *printthread2(void *arg)
pthread_barrier_wait(&barrier);
return null;
}void *printthread3(void *arg)
pthread_barrier_wait(&barrier);
return null;
}
pthread_cond_wait()函式說明:[1] 搶占到互斥鎖並執行到條件if (flag != 1)之後,執行緒阻塞在條件變數
[2] pthread_cond_wait()內部會解鎖,然後等待條件變數被其他執行緒啟用
[3] 被啟用後會再自動加鎖(在其他執行緒釋放互斥鎖之後)
[4] 並重新判斷條件變數阻塞條件是否成立,成立重新掛起,不成立則繼續往下執行
acknowledgements:
2017.08.31
多執行緒程式設計 互斥鎖 條件變數
一,互斥鎖 在多工作業系統中,有很多任務同時執行,這些任務可能會用到同乙個資源,如果沒有一種機制來控制這些任務共享同乙個資源,那這些任務可能無法正常使用自己想用的資源。互斥鎖 是多工作業系統中一種簡單的加鎖方法,來控制各任務對共享資源的訪問。互斥鎖的狀態 上鎖 lock 和解鎖 unlock 互斥鎖...
linux 多執行緒程式設計 互斥鎖與條件變數
條件變數是利用執行緒間共享的全域性變數進行同步的一種機制,主要包括兩個動作 乙個執行緒等待 條件變數的條件成立 而掛起,另乙個執行緒使 條件成立 給出條件成立訊號 為了防止競爭,條件變數的使用總是和乙個互斥鎖結合在一起。下面這個例子展示的是互斥鎖和條件變數的結合使用,以及取消對於條件等待動作的影響,...
Linux C 多執行緒程式設計互斥鎖與條件變數
linux c 多執行緒程式設計互斥鎖與條件變數 include mylib.h define buffer size 5 產品庫存大小 define product cnt 30 產品生產總數 struct product cons buffer void init struct product ...