多執行緒程式設計 互斥鎖 條件變數 關卡的使用例項

2021-08-07 14:32:22 字數 3553 閱讀 8971

之前的文章已經回顧了多執行緒同步的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 ...