用MFC編寫多執行緒程式常用函式

2021-08-16 03:04:39 字數 4366 閱讀 1756

1.訊號量建立函式createsemaphore(null,initialvalue,maxvalue,null)

該函式的返回值為指向訊號量的控制代碼,之後通過該控制代碼來使用訊號量;

該函式第乙個引數為安全屬性,一般情況下預設為null;

第二個引數為訊號量的初始值;

第三個引數為訊號量的最大值;

第四個引數為訊號量名稱,我是通過控制代碼來使用訊號量的,因此名稱都寫成null;

為了簡單起見,我沒有用createmutex()函式來建立互斥鎖,而是建立了初始值為1最大值也為1的訊號量來替代,**如下:handle bmutex = createsemaphore(null,1,1,null);//建立對箱子互斥訪問的鎖;

普通訊號量建立**:

handle bempty = createsemaphore(null,box1size,box1size,null);//建立空緩衝區的訊號量控制代碼

handle bfull = createsemaphore(null,0,box1size,null);//建立滿緩衝區的訊號量的控制代碼

2.訊號量使用函式dword waitforsingleobject(handle hhandle,dword dwmilliseconds);

第乙個引數為要使用的訊號量的控制代碼,控制代碼由訊號量建立函式得到; 

第二個引數為判斷訊號量是否可使用的等待時間,單位為毫秒;

如果在等待時間內訊號量變得可以使用,返回wait_object_0,如果等待時間到達上限訊號量還是無法使用,則函式返回wait_timeout,可以根據兩種情況下的不同的函式返回值來判斷訊號量是否可使用; 

引數dwmilliseconds有兩個具有特殊意義的值:0和infinite。若為0,則該函式立即返回;若為infinite,則執行緒一直被掛起,直到hhandle所指向的物件變為有訊號狀態時為止;

但是在課設過程中老師說盡量不要使用infinite,而是使用乙個確定的值來代替(如1000),再通過乙個死迴圈來不停監測,這樣做是因為會不停地監測訊號量是否可用,如果此時結束正在執行這段**的程序程式會報錯,無法正常退出,**示例如下:

while(true)

else

如果需要同時等待多個訊號量,則應該使用函式dword waitformultipleobjects( )來同時獲得多個訊號量使用權,這樣可以避免程序互相占有資源而導致的死鎖問題,函式原型為:dword waitformultipleobjects( 

dword ncount, // 等待的物件數量 

const handle *lphandles, // 物件控制代碼陣列指標 

bool fwaitall, // 等待方式,為true表示等待全部物件都變為有訊號狀態才返回,為false表示任何乙個物件變為有訊號狀態則返回

dword dwmilliseconds // 超時設定,以ms為單位,如果為infinite表示無限期的等待 ); 

3.訊號量釋放函式bool releasesemaphore( handle hsemaphore,long lreleasecount,lplong lppreviouscount ); 

第乙個引數為訊號量控制代碼;

第二個引數為釋放的資源的數量;

第三個引數為資源原始值,可以用來得到釋放前訊號量的值,我的**中不需要該值因此設定為了null;

4.執行緒建立函式

執行緒建立函式一:

注意:作業系統提供的執行緒建立函式,給編譯廠商用,編寫程式時最好不使用

handle createthread(

lpsecurity_attributes lpthreadattributes,

dword dwstacksize,

lpthread_start_routine lpstartaddress, 

lpvoid lpparameter,

dword dwcreationflags, 

lpdword lpthreadid);

該函式在其呼叫程序的程序空間裡建立乙個新的執行緒,並返回已建執行緒的控制代碼 handle 

lpsecurity_attributes lpthreadattributes:指向乙個 security_attributes 結構的指標,該結構決定了執行緒的安全屬性,一般置為 null; 

dword dwstacksize:指定了執行緒的堆疊深度,一般都設定為0; 

lpthread_start_routine lpstartaddress :表示新執行緒開始執行時**所在函式的位址,即執行緒的起始位址。一般情況為(lpthread_start_routine)threadfunc,threadfunc 是執行緒函式名; 

lpvoid lpparameter :指定了執行緒執行時傳送給執行緒的32位引數,即執行緒函式的引數; 

dword dwcreationflags :控制線程建立的附加標誌,可以取兩種值。如果該引數為0,執行緒在被建立後就會立即開始執行;如果該引數為create_suspended,則系統產生執行緒後,該執行緒處於掛起狀態,並不馬上執行,直至函式resumethread被呼叫; 

lpdword lpthreadid  lpthreadid:該引數返回所建立執行緒的id; 

如果建立成功則返回執行緒的控制代碼,否則返回null。

執行緒建立函式二:

注意:該執行緒建立函式在c/c++中使用,不再mfc中使用;

_beginthreadex()函式在建立新執行緒時會分配並初始化乙個_tiddata塊用於存放一些執行緒需要獨享的資料;

函式原型為unsigned long _beginthreadex(void*security,unsigned stack_size,unsigned(__stdcall* start_address(void*),void * arglist,unsigned initflag,unsigned * thrdaddr);

第乙個引數為安全屬性,null預設為安全屬性;

第二個引數用來指定執行緒堆疊大小,0代表和建立它的執行緒相同;

第三個引數用來指定執行緒函式的位址,傳遞進來函式名稱即可;

第三個引數為傳遞給執行緒的引數指標,一般都會用乙個結構體來表示;

第四個引數指定執行緒初始狀態,0表示立即執行,create_suspend表示懸掛程序;

第五個引數用於記錄執行緒id的位址,不需要id位址時預設為null;

執行緒建立函式三:

該函式用於mfc中

函式原型為handle afxbeginthreadex(vunsigned(__stdcall* start_address(void*),void * arglist);

該函式引數只有執行緒函式入口和傳遞給執行緒的函式指標兩個引數,其餘引數都為預設屬性,返回值為執行緒控制代碼;

三個執行緒建立函式的比較:

由於第一種建立方式不適合在程式設計當中使用,因此不做過多的比較;

第二種和第三種執行緒建立函式只是針對不同的語言來使用,他們都需要得到指定執行執行緒函式的位址(即函式名稱),_beginthreadex()函式的執行緒執行函式原型為unsigned int __stdcall worker3thread(pvoid pparam),afxbeginthread()為nsigned int worker3thread(pvoid pparam),執行緒執行函式內可使用乙個死迴圈來控制線程執行內容

除此之外,他們都需要傳遞乙個引數指標進去,在我的**中,我將需要的所有引數全部封裝進乙個結構體中傳入;

節選其中部分**:

//建立worker1執行緒

for(int i=0; iworker1 = worker_1[i];

worker_1[i]->worker1handle = afxbeginthread(worker1thread,worker1thread)->m_hthread; }

//呼叫的執行緒執行函式

unsigned int worker1thread(pvoid pparam)

return 0; }

5.執行緒掛起函式:該函式用於掛起指定的執行緒,如果函式執行成功,則執行緒的執行被掛起;

dword suspendthread(handle hthread);

6.執行緒喚醒函式:該函式用於結束執行緒的掛起狀態,執行執行緒;

dword resumethread(handle hthread);

7.執行緒終止函式:

bool terminatethread(handle hthread,dword dwexitcode);

第二個引數用於指定執行緒的退出碼;

注意:課設過程中老師不建議使用該函式,因為這種方法是非常「暴力」的,該函式用於強行終止某個正在執行的程序,但這種執行是不安全的,可能會引起系統不穩定,雖然該函式立即終止執行緒的執行,但並不釋放執行緒所占用的資源,為了避免這種情況的發生,可以將乙個bool型變數放入while迴圈中來控制線程執**況,正常執行置為true,如果需要終止執行緒,則將變數置為false,這樣做會終止while迴圈,使執行緒執行函式正常返回,執行緒正常結束;

用BCB編寫多執行緒應用程式

隨著windows系統的全球性普及,多執行緒技術已越來越多地運用到許多軟體設計中。使用多執行緒技術可全面提高應用程式的執行效率。以前為了實現多執行緒程式設計,基本上都是呼叫一系列的api函式,如createthread resumethread等,不容易控制,還容易出錯。在使用bcb以後,我才發現原...

用BCB編寫多執行緒應用程式

隨著windows系統的全球性普及,多執行緒技術已越來越多地運用到許多軟體設計中。使用多執行緒技術可全面提高應用程式的執行效率。以前為了實現多執行緒程式設計,基本上都是呼叫一系列的api函式,如createthread resumethread等,不容易控制,還容易出錯。在使用bcb以後,我才發現原...

編寫java多執行緒爬蟲程式

所謂爬蟲程式,就是模擬瀏覽器傳送http請求給web 這裡我們實現乙個這樣的爬蟲程式 列出segmentfault 中指定使用者所有文章及其閱讀人數的程式 基本思路是這樣的 1我們進入某使用者的文章列表頁 2獲得文章列表 3對文章逐個訪問 4獲取文章頁面的閱讀數 比如以我的主頁舉例 1 進入文章列表...