多執行緒第一篇:使用_beginthreadex建立執行緒
阿新 • • 發佈:2019-02-03
我們先來了解一下執行緒的相關函式:
CreateThread函式:
第二個引數是用於新執行緒的初始堆疊大小,預設值為0。在任何情況下,Windows根據需要動態延長堆疊的大小。
第三個引數是指向執行緒函式的指標。函式名稱沒有限制,但是必須以下列形式宣告:
DWORD WINAPI ThreadProc (PVOID pParam) ;
第四個引數為傳遞給ThreadProc的引數。這樣主執行緒和從屬執行緒就可以共享資料。
第五個引數通常為0,但當建立的執行緒不馬上執行時為旗標CREATE_SUSPENDED。執行緒將暫停直到呼叫ResumeThread來恢復執行緒的執行為止。
第六個引數是一個指標,指向接受執行緒ID值的變數。
WaitForSingleObject:等待一個object觸發,引數為object的控制代碼
第二個引數為最長等待的時間,以毫秒為單位,如傳入5000就表示5秒,傳入0就立即返回,傳入INFINITE表示無限等待。即返回,傳入INFINITE表示無限等待。
函式返回值:
WAIT_OBJECT_0:在指定的時間內物件被觸發,函式返回WAIT_OBJECT_0。
WAIT_TIMEOUT:超過最長等待時間物件仍未被觸發返回WAIT_TIMEOUT。
WAIT_FAILED: 傳入引數有錯誤將返回WAIT_FAILED
_beginthreadex()和CreateThread引數是一樣的,一般來講在建立執行緒的時候儘量要用_beginthreadex(),我們來看看原因:
由於標準c程式庫中有許多全域性變數,當一個執行緒改變全域性變數的時候會影響到其他執行緒,或者整個程序,例如c語言中的errno.
為了解決這個問題,Windows作業系統提供了這樣的一種解決方案——每個執行緒都將擁有自己專用的一塊記憶體區域來供標準C執行庫中所有有需要的函式使用。而且這塊記憶體區域的建立就是由C/C++執行庫函式_beginthreadex()來負責的。
_beginthreadex()函式在建立新執行緒時會分配並初始化一個_tiddata塊。這個_tiddata塊自然是用來存放一些需要執行緒獨享的資料。事實上新執行緒執行時會首先將_tiddata塊與自己進一步關聯起來。然後新執行緒呼叫標準C執行庫函式如strtok()時就會先取得_tiddata塊的地址再將需要保護的資料存入_tiddata塊中。這樣每個執行緒就只會訪問和修改自己的資料而不會去篡改其它執行緒的資料了。因此,如果在程式碼中有使用標準C執行庫中的函式時,儘量使用_beginthreadex()來代替CreateThread().
(-----來自http://blog.csdn.net/morewindows/article/details/7421759)
注意:
(1)C++主執行緒終止時,同時也會終止所有主執行緒建立的子執行緒,不管子執行緒有沒有執行完畢。
(2)如果某執行緒掛起,然後有呼叫WaitForSingleObject等待該執行緒,就會導致死鎖。
( 3 ) 執行緒執行時候,事件處於未觸發,執行完畢後自動設為觸發狀態.
CreateThread函式:
第一個引數是指向SECURITY_ATTRIBUTES型態的結構的指標。在Windows 98中忽略該引數。在Windows NT中,它被設為NULL。HANDLE WINAPI CreateThread ( _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes , // pointer to security attributes _In_ SIZE_T dwStackSize, // initial thread stack size _In_ LPTHREAD_START_ROUTINE lpStartAddress, // pointer to thread function _In_opt_ LPVOID lpParameter, // argument for new thread _In_ DWORD dwCreationFlags, // creation flags _Out_opt_ LPDWORD lpThreadId // pointer to receive thread ID );
第二個引數是用於新執行緒的初始堆疊大小,預設值為0。在任何情況下,Windows根據需要動態延長堆疊的大小。
第三個引數是指向執行緒函式的指標。函式名稱沒有限制,但是必須以下列形式宣告:
DWORD WINAPI ThreadProc (PVOID pParam) ;
第四個引數為傳遞給ThreadProc的引數。這樣主執行緒和從屬執行緒就可以共享資料。
第五個引數通常為0,但當建立的執行緒不馬上執行時為旗標CREATE_SUSPENDED。執行緒將暫停直到呼叫ResumeThread來恢復執行緒的執行為止。
第六個引數是一個指標,指向接受執行緒ID值的變數。
WaitForSingleObject:等待一個object觸發,引數為object的控制代碼
DWORD WINAPI WaitForSingleObject(
_In_ HANDLE hHandle,
_In_ DWORD dwMilliseconds
);
第一個引數為要等待的核心物件。第二個引數為最長等待的時間,以毫秒為單位,如傳入5000就表示5秒,傳入0就立即返回,傳入INFINITE表示無限等待。即返回,傳入INFINITE表示無限等待。
函式返回值:
WAIT_OBJECT_0:在指定的時間內物件被觸發,函式返回WAIT_OBJECT_0。
WAIT_TIMEOUT:超過最長等待時間物件仍未被觸發返回WAIT_TIMEOUT。
WAIT_FAILED:
_beginthreadex()和CreateThread引數是一樣的,一般來講在建立執行緒的時候儘量要用_beginthreadex(),我們來看看原因:
由於標準c程式庫中有許多全域性變數,當一個執行緒改變全域性變數的時候會影響到其他執行緒,或者整個程序,例如c語言中的errno.
為了解決這個問題,Windows作業系統提供了這樣的一種解決方案——每個執行緒都將擁有自己專用的一塊記憶體區域來供標準C執行庫中所有有需要的函式使用。而且這塊記憶體區域的建立就是由C/C++執行庫函式_beginthreadex()來負責的。
_beginthreadex()函式在建立新執行緒時會分配並初始化一個_tiddata塊。這個_tiddata塊自然是用來存放一些需要執行緒獨享的資料。事實上新執行緒執行時會首先將_tiddata塊與自己進一步關聯起來。然後新執行緒呼叫標準C執行庫函式如strtok()時就會先取得_tiddata塊的地址再將需要保護的資料存入_tiddata塊中。這樣每個執行緒就只會訪問和修改自己的資料而不會去篡改其它執行緒的資料了。因此,如果在程式碼中有使用標準C執行庫中的函式時,儘量使用_beginthreadex()來代替CreateThread().
(-----來自http://blog.csdn.net/morewindows/article/details/7421759)
注意:
(1)C++主執行緒終止時,同時也會終止所有主執行緒建立的子執行緒,不管子執行緒有沒有執行完畢。
(2)如果某執行緒掛起,然後有呼叫WaitForSingleObject等待該執行緒,就會導致死鎖。
( 3 ) 執行緒執行時候,事件處於未觸發,執行完畢後自動設為觸發狀態.