1. 程式人生 > >VS C++ 執行緒篇之執行緒同步

VS C++ 執行緒篇之執行緒同步

執行緒同步解決
        不同執行緒函式的執行順序,進行執行緒協調。  

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