今天看到一篇文章(講到主線程等待子執行緒執行完畢,如何判斷的問題.作者一開始採用的是簡單的sleep操作,但這種操作不能夠保證正確而且效率還比較低.
於是作者自己設計了判斷子執行緒結束的方法,我也就實踐了這個方法.(其實windows中提供的有系統函式來滿足需求,它就是waitformultipleobjects,不過自己設計還是更有成就感的)
在設計子執行緒時,我考慮可以採用採用隨機數的方式來模擬不同執行緒處理時間不同的情況;而子執行緒中引數是把主線程迴圈的下標i傳進來,考慮這樣應該可以滿足需求.最後結果讓人吃驚.
發現結果竟然列印的都是第20個執行緒.按理來說i是從0到19的.出現這種情況的原因是主線程中把所有的子執行緒都建立完後,才去執行子執行緒中的內容,此時i的值都變成了20了.
我這個時候,想到了使用同步的方式來解決,比如在子執行緒和主線程中加上臨界區,後來發現沒有用.因為在createthread的迴圈執行完,子執行緒才開始執行,因此根本就不存在同時訪問的事情,所以同步談不上.
看來這種方法是行不通的,從設計上來說一開始就存在問題吧.
(1)多執行緒共享的變數要選擇全域性變數
(2)createthread後面沒有sleep,會導致子執行緒建立完後沒有及時啟動.
有一種比較蹩腳的改法,現有**不動,在createthread後面新增sleep(2000),這個實際上就是壞味道了.
#include #include"windows.h
"#include
"stdlib.h
"using
namespace
std;
#define max 2000
#define min 0
#define threadnum 20
int g_nflag[threadnum] = ;
dword winapi threadfun(
void *param)
intmain()
//等待執行緒全部結束.
//方法2:自己創造方法實現
while (1
)
}cout
<< "
子執行緒已完全結束掉!
"
; }
return0;
}
執行結果.
第20個執行緒,休眠時間為45第20個執行緒,休眠時間為51ms
第20個執行緒,休眠時間為54ms
第20個執行緒,休眠時間為64ms
第20個執行緒,休眠時間為51ms
ms當前的i:0
第20個執行緒,休眠時間為45ms
第20個執行緒,休眠時間為64ms
第20個執行緒,休眠時間為103ms
第20個執行緒,休眠時間為103ms
第20個執行緒,休眠時間為103ms
第20個執行緒,休眠時間為103ms
第20個執行緒,休眠時間為103ms
既然之前的設計就不夠合理,那就不在上面縫縫補補了,換一種相對正確的方式來做.
去在一開始定義乙個全域性變數g_nthreadno,在子執行緒中進行自增,這樣就不會出現和主線程扯不清的聯絡了.
#include"windows.h
"#include
"stdlib.h
"using
namespace
std;
#define max 2000
#define min 0
#define threadnum 20
int g_nflag[threadnum] = ;
int g_nthreadno = 0
;critical_section g_sc;
dword winapi threadfun(
void *param)
intmain()
//方法2:自己創造方法實現
while (1
)
}cout
<< "
子執行緒已完全結束掉!
"
; }
deletecriticalsection(&g_sc);
return0;
}
這個時候的列印是這樣的:
第0個執行緒,休眠時間為38ms第1個執行緒,休眠時間為41ms
當前的i:
0第2個執行緒,休眠時間為45ms
第3個執行緒,休眠時間為48ms
當前的i:
2第4個執行緒,休眠時間為51ms
第5個執行緒,休眠時間為54ms
當前的i:
4第6個執行緒,休眠時間為58ms
當前的i:
6第7個執行緒,休眠時間為61ms
第8個執行緒,休眠時間為64ms
當前的i:
7第9個執行緒,休眠時間為68ms
當前的i:
9第10個執行緒,休眠時間為71ms
第11個執行緒,休眠時間為74ms
當前的i:
10第12個執行緒,休眠時間為77ms
當前的i:
12第13個執行緒,休眠時間為81ms
當前的i:
13第14個執行緒,休眠時間為84ms
當前的i:
14第15個執行緒,休眠時間為87ms
當前的i:
15第16個執行緒,休眠時間為90ms
當前的i:
16第17個執行緒,休眠時間為94ms
當前的i:
17第18個執行緒,休眠時間為97ms
當前的i:
18第19個執行緒,休眠時間為100ms
當前的i:
19子執行緒已完全結束掉!
這裡要注意:
對子執行緒中的g_nthreadno進行同步操作,不然他們會同時訪問g_nthreadno,造成意想不到的問題.
比如當時產生的結果是這樣的:
列印出來的文字是交叉的;列印都是0執行緒,但最後g_nflag[g_nthreadno] = 1的操作卻是正確的.
單步調了下,發現原因是子執行緒先都執行了cout那一行,然後後面的賦值和自增部分又能夠交替進行了.
第0個執行緒,休眠時間為38第0第0第0個執行緒,休眠時間為38ms第0個執行緒,休眠時間為38ms
第0個執行緒,休眠時間為38ms
第0第0第0第0個執行緒,休眠時間為38ms
第0個執行緒,休眠時間為38ms
第0個執行緒,休眠時間為38ms
個執行緒,休眠時間為38ms
個執行緒,休眠時間為38第0個執行緒,休眠時間為38ms
第0個執行緒,休眠時間為38ms
第0個執行緒,休眠時間為38ms
ms第0個執行緒,休眠時間為38ms
ms個執行緒,休眠時間為38ms
第0個執行緒,休眠時間為38ms
個執行緒,休眠時間為38ms
第0個執行緒,休眠時間為38ms
第0個執行緒,休眠時間為38ms
第0個執行緒,休眠時間為38ms
個執行緒,休眠時間為38ms
當前的i:0子執行緒已完全結束掉!請按任意鍵繼續. . .
ps:
採用windows自帶的系統函式,用起來就很開心了.
critical_section g_sc;dword winapi threadfun(
void *param)
intmain()
//等待執行緒全部結束.
//方法1:使用系統提供的方法
waitformultipleobjects(threadnum, h, true, infinite);
deletecriticalsection(&g_sc);
return0;
}
C 主線程等待子執行緒執行結束
佐左佑右 原文 c 主線程等待子執行緒執行結束 由於主程式中呼叫matlab的dll檔案進行計算要用較長的時間,主介面會有很長時間的卡頓,造成的使用者感受十分不好,因此我想在呼叫時,將呼叫放入子執行緒中,然後在主線程中彈出乙個提示框,顯示資料正在載入,等子執行緒執行結束後,主線程繼續工作。使用的是中...
java執行緒池主線程等待子執行緒執行完成
今天討論乙個入門級的話題,不然沒東西更新對不起空間和網域名稱 工作總往往會遇到非同步去執行某段邏輯,然後先處理其他事情,處理完後再把那段邏輯的處理結果進行彙總的產景,這時候就需要使用執行緒了.乙個執行緒啟動之後,是非同步的去執行需要執行的內容的,不會影響主線程的流程,往往需要讓主線程指定後,等待子執...
Java主線程等待所有子執行緒執行完畢
需求 main方法中建立了執行緒,子執行緒沒有執行結束的時候主線程執行結束了,利用join又不能保證併發執行,目的是主線程等待其子執行緒執行完成之後退出 實現 利用hook實現jvm的等待執行 業務執行緒 class customerthread implements runnable catch ...