當自增 減( )遇上多執行緒

2021-07-24 04:48:13 字數 2145 閱讀 9753

本文主要講述,在剛接觸多執行緒程式設計時,將自增變數作為引數傳進執行緒函式時,發生的「奇異」現象。

事情是這樣的:生成1000w隨機數,建立n個執行緒,將這些隨機數隨機的寫到這n個檔案中,每個隨機數在乙個檔案中佔一行。對於生成的n個檔案的檔名沒有要求。當時的分析如下:(1)先將這些隨機數存起來,然後多執行緒取時,使用互斥鎖來保證各執行緒間的同步;(2)儲存的容器自然想到stl佇列,但是佇列每次取完還要刪除對首元素,在本題中取完的隊首元素沒必要刪除,因為1000w隨機數是一次性生成的,而且stl佇列由於是分段連續的儲存設計,具有複雜的迭代器設計,訪問速度自然不是很快,基於此,使用了vector容器進行儲存;(3)各執行緒什麼時候結束工作而返回主線程了?等隊列為空(或者下文**中的vector下標到容器尾)就可以結束工作退出了!(4)檔案如何命名了?如果用for迴圈建立n個執行緒,那麼只要把for迴圈中的迴圈變數傳進執行緒不就可以了嗎?(小心,問題就出於此!!!)

基於上述分析,寫出的**如下:

#include 

#include

#include

#include

#include

#include

#include

using

namespace

std;

const

int maxthreads = 16;

unsigned

int curindex = 0;

unsigned

int randomnums = 10000000;

vector

numbers;//存放隨機數的容器

pthread_mutex_t m_mutex;

bool getnumber(int &num)

num = numbers[curindex];

++curindex;

pthread_mutex_unlock(&m_mutex);

return

true;

}void* worker(void *arg)

int n;

while(1)

else

int main()

int err;

for(i = 0 ; i < num ; ++i)

}//阻塞等待

for(i = 0 ; i < num ; ++i)

}numbers.clear();

vector

().swap(numbers);

pthread_mutex_destroy(&m_mutex);

return

0;}

編譯執行:

g++ -g main.cpp -o run -lpthread

執行:

[root@localhost threads]# ./run

please input thread number:2

thread 3086228368 is running

thread 3075738512 is running

當輸入兩個執行緒時,確實建立了兩個執行緒!但實際中只生成了乙個結果檔案,這乙個結果檔案中包含了1000w個隨機數:

-rw-r–r– 1 root root 39160744 oct 29 19:44 0.txt

[root@localhost threads]# wc -l *.txt

10000000 0.txt

好吧,還有乙個檔案了?為什麼1000w的隨機數全都在乙個檔案中?

既然是這樣,那麼說明兩個執行緒都只去讀寫了乙個檔案,也就是說兩個執行緒拿到的引數idx = ((int)arg);是一樣的!

回頭看看建立執行緒的操作吧!

喔! 考慮變數i自增的操作,實際上可以分解為以下3步:(1)從記憶體單元讀入暫存器;(2)在暫存器中對變數做增量操作;(3)把新的值寫回記憶體單元。如果兩個執行緒試圖幾乎在同一時間對同一變數做增量操作而不進行同步的話,結果可能就不一致了,在上述**中,我們傳進執行緒函式的是變數的位址,那麼變數i自增後,可能還沒有寫回記憶體單元,就被另乙個執行緒讀取了,那為什麼不是只建立了乙個執行緒了,而是確確實實建立了兩個執行緒了,可能是編譯器做了優化吧,for迴圈裡第一次從記憶體取出後,之後都是直接從暫存器中取出!

那本題該如何了,改用執行緒id做檔名吧!還有其他方法嘛?

《當阿呆遇上阿瓜》 當鐵鍬遇上石頭

該片是金 凱瑞成名之前在1994年給影迷奉獻的搞怪喜劇片 阿呆與阿瓜 的續集,說是續集,其實是前傳。新線公司讓我們足足等了10年才看到續集,然而此時影片的主創人員全部更換。少了金 凱瑞,似乎再沒有理由讓我們更期待看到這部影片。可別說筆者心態不正,筆者之所以看此片僅僅因為想看看新線公司是如何挖這塊金礦...

當技術遇上管理

哈佛商學院教授戴維 蓋兒文總結說過 我們的時間應該花在設計和除bug上,而不是不停地與上司打交道,或者監督別人的工作。作為乙個技術人員管理者,要麼你的技術能力徹底讓人信服,要麼你的想法與綜合能力高人一籌,而且還得顯得比手下的人要忙,不然誰心甘情願服從你的安排。很不巧,國內大多數公司裡,有些人的存在,...

當敏捷遇上銷售

在文章 敏捷與銷售 我的第一支scrum銷售團隊 中,對於大家經常關心的問題 是否能將銷售團隊做成敏捷的以及如何推動變革?銷售經理 eric krisfelt給出了自己的解答。他詳細描述了如何在銷售組織中實現scrum的步驟,並展示給大家非工程師團隊如何變成有自組織意識的敏捷團隊。在開始過渡之前,e...