乙個有趣的多執行緒問題

2021-06-29 13:53:09 字數 2326 閱讀 6663

師弟問了個非常有趣的多執行緒問題,之前沒有關注,這裡寫下自己的心得。

對於如下**:

#include #include #include uint winapi fun1proc(lpvoid lpparameter);

uint winapi fun2proc(lpvoid lpparameter);

int index1=0;

int index2=0;

void main()

uint winapi fun1proc(lpvoid lpparameter)

return 0;

}uint winapi fun2proc(lpvoid lpparameter)

return 0;

}

那麼按照cpu切片交換執行兩個執行緒來算,應該是每個執行緒在切片時間內輸出幾行,如此交替迴圈,如下:

thread1-1

thread1-2

thread1-3

thread1-4

thread2-1

thread2-2

thread2-3

thread1-5

thread1-6

thread2-4

thread2-5

thread2-6

...

但是實際輸出為:

thread1-1

thread1-2

thread2-1

thread1-3

thread2-2

thread1-4

thread2-3

thread1-5

thread2-4

thread1-6

thread2-5

...thread1-99

thread2-98

thread1-100

thread2-99

thread2-100

如果不是看這段程式,這種嚴格的交替輸出都要讓我們以為在程式中我們已經做了執行緒同步了。

仔細思考,許多地方使用類似的程式做多執行緒切片不可依賴的演示。這裡這樣的結果考慮可能是系統排程演算法做了調整或cpu多核的問題,對於cpu多核的問題測試不是這個原因,那麼剩下的就是cpu排程演算法的問題了,這裡考慮兩個執行緒計算量一樣,所以交替輸出,我們人為調整其中乙個的執行緒計算量。

如下:

uint winapi fun1proc(lpvoid lpparameter)

return 0;

}uint winapi fun2proc(lpvoid lpparameter)

return 0;

}

可以多執行幾次程式,好多結果是不一樣的,取其中一次結果如下:

thread2-1

thread2-2

thread2-3

thread2-4

thread1-1

thread2-5

thread2-6

thread2-7

thread1-2

thread2-8

thread2-9

thread2-10

thread2-11

thread1-3

...

可以看到這時候,執行緒的輸出就不是那麼有規律了。

其實說這麼多,這個演示程式無非就是為了說明乙個問題,不能依賴cpu切片來完成執行緒同步或者說cpu切片是不可控的

要完成執行緒同步,必須使用執行緒同步量,下面使用互斥量完成交替輸出:

#include #include #include uint winapi fun1proc(lpvoid lpparameter);

uint winapi fun2proc(lpvoid lpparameter);

int index1=0;

int index2=0;

handle hmutex;

void main()

uint winapi fun1proc(lpvoid lpparameter)

return 0;

}uint winapi fun2proc(lpvoid lpparameter)

return 0;

}

呵呵,這個問題沒什麼,就是說明執行緒同步一定要使用同步量,額,貌似這個大家都知道。。。

乙個有趣的問題

今早朋友圈某人以100軟妹幣求助這樣乙個問題 概率論是學的一塌糊塗,但是突然想起類似用蒙特卡洛方法可以模擬出來概率。於是向著這100軟妹幣出發了。但是首先遇到了第乙個問題。陣列b的亂序排列感覺有點棘手。首先的第一反應是 迴圈隨機產生1 100的隨機數,判斷陣列中是否已經有該數,若已存在,則重新生成隨...

乙個多執行緒同步問題

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

請教乙個多執行緒的的問題

我用c 寫了乙個多執行緒的程式 這個程式開很多埠接收資料,每個埠分配了乙個執行緒接受 每個接受執行緒對應還有乙個執行執行緒,執行一些需要阻塞的函式 我接受網路的執行緒用迴圈的方式察看是否有資料。每個迴圈用thread.suspend 掛起 同樣,配套的阻塞程序也在不停迴圈,每個迴圈thread.su...