真正完成**執行的是執行緒,而程序知識執行緒的容器,或者說是執行緒的執行環境。
執行緒有兩部分組成:執行緒的核心物件和執行緒棧
#include
#include
using namespace std;
dword winapi func1proc(lpvoid lpparameter);
dword winapi func2proc(lpvoid lpparameter);
int index = 0;
int tickets = 100;
handle hmutex;
void main()
dword winapi func1proc( lpvoid lpparameter)
else
releasemutex(hmutex);
}return 0;
}dword winapi func2proc( lpvoid lpparameter)
else
releasemutex(hmutex);
}return 0;
}建立執行緒引數說明:
handle createthread(
lpsecurity_attributes lpthreadattributes,//設定為null,則指定預設的安全屬性,如果希望所有的子程序能夠繼承該執行緒物件的控制代碼,則需要設定該結構體,並將結構體中binherithandle成員初始化為true
dword dwstacksize,//設定線棧初始化大小,如果值為0,那麼預設將使用與呼叫該函式的餓執行緒相同的棧空間大小
lpthread_start_routine lpstartaddress,//新執行緒的其實位址,一般為乙個函式名
lpvoid lpparameter,//向新執行緒函式傳遞的引數
dword dwcreateionflags,//建立標誌:為create_suspended就處於暫停狀態,直至呼叫resumethread函式。如果值為0,就立即執行
lpdword lpthreadid//輸出引數,接收執行緒的id,可以為null
);建立互斥物件的引數說明:
handle createmutex(
lpsecurity_attributes lpmutexattributes,//執行互斥物件的安全屬性,可以為null
bool binitialowner,//指定互斥物件初始的擁有者
lpctstr lpname//指定互斥物件的名稱,如果值為null,則建立的是乙個匿名的互斥物件
);請求和釋放互斥物件:
dword waitforsingleobject( handle hhandle, dword dwmilliseconds);
dwmilliseconds指定等待時間的間隔,以毫秒為單位。如果將此引數設定為infinite,則該函式會永遠等待,知道等待的物件處於有訊號狀態才會返回。
bool releasemutex( handle hmutex);
對於互斥物件來說,它是唯一與執行緒相關的核心物件。當主線程擁有互斥物件時,作業系統會將互斥物件的執行緒id設定為主執行緒的id。當其他執行緒中呼叫releasemutex函式釋放互斥物件的所有權時,作業系統會判斷該執行緒的執行緒id與互斥物件內部所維護的執行緒id是否相等,只有相等才能完成釋放操作。也就是說,對互斥物件來說,誰擁有誰釋放。
同樣,當呼叫waitforsingleobject函式時,作業系統也會去判斷當前請求互斥物件的執行緒的id是否與互斥物件當前擁有者的執行緒id相等,如果相等,即使該互斥物件處於未通知狀態,呼叫執行緒任然能夠獲得其所有權,然後waitforsingleobject函式返回。對於同乙個執行緒多次擁有的互斥物件來說,該互斥物件內部的計數器記錄了該執行緒擁有的次數,也就是說:當乙個執行緒擁有互斥物件以後,再次呼叫waitforsingleobject函式,互斥物件的計數器就增加1,當呼叫releasemutex函式釋放互斥物件的所有權時,互斥物件的計數器減1,如果該計數器的值不為0,那麼該互斥物件任然處於未通知狀態。
保證應用程式只有乙個例項執行:
要實現只有乙個例項執行的功能,可以通過命名的互斥物件來實現。在呼叫createmutex函式建立乙個命名的互斥物件後,如果其返回值是乙個有效的就控制代碼,那麼可以接著呼叫getlasterror函式,如果該函式返回的是error_already_exists,這就表明先前已經建立了這個命名的互斥物件,因此就可以知道先前已經有該應用程式的乙個例項在執行了。當然,如果getlasterror函式返回的不是error_already_exists,就說明這個互斥物件是新建立的,從而也就知道當前啟動的這個程序是應用程式第乙個例項。
在mfc中提供了乙個完成版本協商的函式:
bool afxsocketinit( wsadata * lpwsdata = null );//應該在應用程式類過載的initinstance函式中呼叫afxsocketinit函式。
定義乙個執行緒用以接收訊息:
dword winapi cchatdlg::recvproc(lpvoid lpparameter)
sprintf(tempbuf, "%s say: %s" , inet_ntoa(addrfrom.sin_addr), recvbuf);
::postmessage(hwnd, wm_recvdata, 0, (lparam)tempbuf);
}return 0;
}網路程式設計補充:
在伺服器端,需要用到sockaddr_in結構的乙個變數,供bind只用,與此同時,還需要定義乙個sockaddr_in變數,用於recvfrom接收時儲存客戶端位址。
在客戶端:
需要定義乙個sockaddr_in變數,供sendto傳送時指定位址。
孫鑫MFC深入詳解 第十五章 多執行緒(一)
windows中的多執行緒程式設計一直是所有程式設計人員感到困難的乙個地方,主要是在windows多執行緒程式設計中,往往要考慮很多的東西,執行緒啟用的多少,執行緒之間的同步問題等等.下面通過模擬火車售票系統來進行講解 include include using namespace std dwor...
孫鑫MFC深入詳解 第十五章 多執行緒(三)
對命名互斥物件進行例項講解,如下 multithread5.cpp include include using namespace std dword winapi threadproc1 lpvoid lpparameter dword winapi threadproc2 lpvoid lppa...
第十五章 執行緒之協程
目錄協助程式,執行緒和程序都是搶占式特點,執行緒和程序的切換我們是不能參與的。而協程是非搶占式特點,協程也存在著切換,這種切換是由我們使用者來控制的。import gevent 如果程式中沒有耗時操作就順序執行。def test1 for i in range 5 print test1.i gev...