乙個經典的多執行緒同步問題 問題引入

2022-04-10 14:22:03 字數 1358 閱讀 6669

下面來看乙個經典的多執行緒的同步和互斥的問題,問題的描述:

主線程啟動10個子執行緒並將表示子線程式號的變數的位址作為引數傳遞給子執行緒。子執行緒接收引數->sleep(50)->全域性變數++->sleep(0)->輸出引數和全域性變數。

要求:1. 子執行緒輸出的線程式號不能重複

2. 全域性變數的輸出必須是遞增的

下面畫個簡單的示意圖:

這個問題的考察點主要是:

1.主線程建立子執行緒並傳入乙個指向變數位址的指標作引數,由於執行緒啟動須要花費一定的時間,所以在子執行緒根據這個指標訪問並儲存資料前,主線程應等待子執行緒儲存完畢後才能改動該引數並啟動下乙個執行緒。這涉及到主線程與子執行緒之間的同步

2.子執行緒之間會互斥的改動和輸出全域性變數。要求全域性變數的輸出必須遞增。這涉及到各子執行緒間的互斥

#include #include #include //全域性資源

long g_nnum;

//子執行緒個數

const int thread_num = 10;

unsigned int __stdcall fun(void *param)

int main(void)

//保證子執行緒全部執行結束並返回

waitformultipleobjects(thread_num, handle, true, infinite);

return 0;

}

執行結果:

原因分析:

正確的流程應該是:

main執行緒建立thread1子執行緒,thread1把i的值讀走,然後main執行緒執行i++。

然後建立第二個執行緒,第二個執行緒再把更新後的i讀走,然後main執行緒執行i++。

現在錯誤的流程:

main執行緒建立thread1子執行緒,然後thread1的建立需要一定的時間,main執行緒執行i++。

之後main執行緒thread2子執行緒,同樣thread2的建立也需要時間,main執行緒執行i++。

然後thread1和thread2建立完成,分別可以執行了,然後讀取i的值,但是這時i的值已經是3,

不是當初main執行緒想傳給它們的值。沒有做好main執行緒和子執行緒的同步處理。

通過執行的結果可以看出完全是混亂和不可預知的。

接下來的幾篇文章將運用windows平台下的手段分析解決這個問題,方法包括關鍵段、事件、互斥量、訊號量等方法。

乙個經典的多執行緒同步問題

本篇文章參考了 程式描述 主線程啟動10個子執行緒並將表示子線程式號的變數位址作為引數傳遞給子執行緒。子執行緒接收引數 sleep 50 全域性變數 sleep 0 輸出引數和全域性變數。要求 1 子執行緒輸出的線程式號不能重複。2 全域性變數的輸出必須遞增。下面畫了個簡單的示意圖 分析下這個問題的...

乙個經典的多執行緒同步問題01 問題重現

程式描述 主線程啟動10個子執行緒並將表示子線程式號的變數位址作為引數傳遞給子執行緒。子執行緒接收引數 sleep 50 全域性變數 sleep 50 輸出引數和全域性變數。要求 1 子執行緒輸出的線程式號不能重複。2 全域性變數的輸出必須遞增。下面畫了個簡單的示意圖 分析下這個問題的考察點,主要考...

乙個多執行緒同步問題

昨天,路過的時候,發現了這個問題 class syncclass catch exception e system.out.println class test implements runnable public void run 輸出結果如圖 其實synchronized void synmth...