VS C++ 執行緒篇之執行緒同步
阿新 • • 發佈:2019-02-15
執行緒同步解決
不同執行緒函式的執行順序,進行執行緒協調。
API
DWORD WINAPI WaitForSingleObject( HANDLE hHandle, // 物件控制代碼 Thread/Event/Job/Mutex/Process/Semaphore/Waitable timer/Memory resource notification DWORD dwMilliseconds // 等待時間,INFINITE一直等待 ); 返回值 WAIT_TIMEOUT 0x00000102L // 等待超時 WAIT_OBJECT_0 0x00000000L // 等待到了指定物件發出訊號狀態 WAIT_ABANDONED 0x00000080L // 當 hHandle 為 mutex 時,擁有mutex的執行緒在結束時沒有釋放核心物件會返回該值。 WAIT_FAILED ((DWORD)0xFFFFFFFF). // 呼叫GetLastError獲得錯誤資訊
DWORD WINAPI WaitForMultipleObjects( DWORD nCount, // 等待執行緒數量(最多MAXIMUM_WAIT_OBJECTS個) const HANDLE* lpHandles, // 執行緒控制代碼指標陣列(包含多個執行緒控制代碼) BOOL bWaitAll, // 是否全部等待,TRUE,若所有執行緒都為已通知狀態則函式返回 WAIT_OBJECT_0 // FALSE 返回值為執行緒核心物件陣列的索引值 DWORD dwMilliseconds // 等待時間 ); 返回值 WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount– 1) WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount– 1) WAIT_TIMEOUT 0x00000102L WAIT_FAILED ((DWORD)0xFFFFFFFF) // 失敗 呼叫GetLastError返回錯誤資訊
例程1:等待子執行緒執行完畢
#include <stdlib.h> #include <stdio.h> #include <windows.h> DWORD WINAPI ThreadProFunc(LPVOID lpParam); int main(int argc, char **argv) { HANDLE hThread; DWORD dwThreadId; hThread = CreateThread( NULL // 預設安全屬性 , NULL // 預設堆疊大小 , ThreadProFunc // 執行緒入口地址 , NULL //傳遞給執行緒函式的引數 , 0 // 指定執行緒立即執行 , &dwThreadId //執行緒ID號 ); WaitForSingleObject(hThread, INFINITE); // 等待執行緒執行完畢 CloseHandle(hThread); //關閉執行緒控制代碼 for(int i = 0; i < 4; i++) { printf("nihao\n"); } system("pause"); return 0; } DWORD WINAPI ThreadProFunc(LPVOID lpParam) { for(int i = 0; i < 4; i++) { printf("hello\n"); } return 0; }
執行結果
hello
hello
hello
hello
nihao
nihao
nihao
nihao
請按任意鍵繼續. . .
例程2:執行緒A給變數賦值,執行緒B取變數的值,主執行緒列印,對變數值順序進行控制
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
int g_iVarA = 10;
int g_iVarB = 30;
int g_iVarC = 0;
HANDLE g_hThreadA;
HANDLE g_hThreadB;
DWORD WINAPI ThreadProFuncA(LPVOID lpParam);
DWORD WINAPI ThreadProFuncB(LPVOID lpParam);
int main(int argc, char **argv)
{
DWORD dwThreadIdA;
DWORD dwThreadIdB;
g_hThreadA = CreateThread( NULL // 預設安全屬性
, NULL // 預設堆疊大小
, ThreadProFuncA // 執行緒入口地址
, NULL //傳遞給執行緒函式的引數
, 0 // 指定執行緒立即執行
, &dwThreadIdA //執行緒ID號
);
g_hThreadB = CreateThread( NULL , NULL, ThreadProFuncB, NULL, 0, &dwThreadIdB);
WaitForSingleObject(g_hThreadB, INFINITE);
CloseHandle(g_hThreadA); //關閉執行緒控制代碼
CloseHandle(g_hThreadB); //關閉執行緒控制代碼
printf("g_iVarC = %d\n", g_iVarC);
system("pause");
return 0;
}
DWORD WINAPI ThreadProFuncA(LPVOID lpParam)
{
g_iVarA = 100;
g_iVarB = 200;
return 0;
}
DWORD WINAPI ThreadProFuncB(LPVOID lpParam)
{
WaitForSingleObject(g_hThreadA, INFINITE);
g_iVarC = g_iVarA + g_iVarB;
return 0;
}
例程3:多個執行緒一起等待操作,返回已經結束執行緒的最小索引
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
HANDLE g_hThread[4];
DWORD WINAPI ThreadProFuncA(LPVOID lpParam);
DWORD WINAPI ThreadProFuncB(LPVOID lpParam);
DWORD WINAPI ThreadProFuncC(LPVOID lpParam);
DWORD WINAPI ThreadProFuncD(LPVOID lpParam);
int main(int argc, char **argv)
{
DWORD dwThreadIdA;
DWORD dwThreadIdB;
DWORD dwThreadIdC;
DWORD dwThreadIdD;
g_hThread[0] = CreateThread( NULL, NULL, ThreadProFuncB, NULL, 0, &dwThreadIdB);
g_hThread[2] = CreateThread( NULL, NULL, ThreadProFuncC, NULL, 0, &dwThreadIdC);
g_hThread[3] = CreateThread( NULL, NULL, ThreadProFuncD, NULL, 0, &dwThreadIdD);
g_hThread[1] = CreateThread( NULL // 預設安全屬性
, NULL // 預設堆疊大小
, ThreadProFuncA // 執行緒入口地址
, NULL //傳遞給執行緒函式的引數
, 0 // 指定執行緒立即執行
, &dwThreadIdA //執行緒ID號
);
DWORD retErr = WaitForMultipleObjects(4, g_hThread, false, INFINITE);
CloseHandle(g_hThread[0]); //關閉執行緒控制代碼
CloseHandle(g_hThread[1]); //關閉執行緒控制代碼
CloseHandle(g_hThread[2]); //關閉執行緒控制代碼
CloseHandle(g_hThread[3]); //關閉執行緒控制代碼
printf("main, retErr = %x\n", retErr); // 正常,返回最小的結束執行緒的索引號
system("pause");
return 0;
}
DWORD WINAPI ThreadProFuncA(LPVOID lpParam)
{
printf("A");
return 0;
}
DWORD WINAPI ThreadProFuncB(LPVOID lpParam)
{
WaitForSingleObject(g_hThread[1], INFINITE);
Sleep(2000);
printf("B");
return 0;
}
DWORD WINAPI ThreadProFuncC(LPVOID lpParam)
{
Sleep(2000);
printf("C\n");
return 0;
}
DWORD WINAPI ThreadProFuncD(LPVOID lpParam)
{
printf("D\n");
return 0;
}
執行結果:D
main, retErr = 3
A請按任意鍵繼續. . . BC