1. 程式人生 > >多執行緒同步之事件 -- 2個執行緒交替列印數字

多執行緒同步之事件 -- 2個執行緒交替列印數字

    有段時間沒有接觸多執行緒相關的知識了,難免會遺忘或者生疏。多執行緒通訊和同步相關的知識運用比較廣,而且比較常見。今天通過2個執行緒交替列印數字的例子,來整理下多執行緒序相關的程式設計方式。這裡2個執行緒直接通過一個event進行同步。

    我們通過CreateEvent函式建立一個無訊號的事件。然後再執行緒1中通過SetEvent設定該事件為有訊號。後續每個執行緒就是通過WaitForSingleObject函式去等待事件即可。通過交替呼叫ResetEvent和SetEvent,2個執行緒相安無事,各自按照順序進行列印。

    如果沒有多執行緒的控制,那麼列印順序一定是不可預測的,原因是執行緒的排程由系統決定,某些執行緒函式執行了2次,可能某些執行緒函式才執行1次。

    測試程式碼如下:

#include <Windows.h>
#include <iostream>

#include <stdlib.h>
#include <process.h>

using namespace std;

int g_number = 0;
HANDLE g_hEvent = NULL;

unsigned int __stdcall threadFun1(void *param)
{

	SetEvent(g_hEvent);
	while(1)
	{
		DWORD dwWaitResult = WaitForSingleObject(g_hEvent, INFINITE); 

		switch (dwWaitResult) 
		{
			// Event object was signaled
			case WAIT_OBJECT_0: 
			break; 
			// An error occurred
			default: 
			printf("Wait error (%d)\n", GetLastError()); 
			return 0; 
		}

		ResetEvent(g_hEvent);

		printf("threadFun1: g_number = %d\t\r\n",g_number++);
		Sleep(1500);

		SetEvent(g_hEvent);
	}

	return 0;
}

unsigned int __stdcall threadFun2(void *param)
{

	while(1)
	{
		DWORD dwWaitResult = WaitForSingleObject(g_hEvent, INFINITE); 

		switch (dwWaitResult) 
		{
			// Event object was signaled
		case WAIT_OBJECT_0: 
			break; 
			// An error occurred
		default: 
			printf("Wait error (%d)\n", GetLastError()); 
			return 0; 
		}

		ResetEvent(g_hEvent);

		printf("threadFun2: g_number = %d\t\r\n",g_number++);
		Sleep(800);

		SetEvent(g_hEvent);
	}

	return 0;
}

int main(int argc,char* argv[])
{
	g_hEvent =  CreateEvent(NULL,false,false,L"Event Test1");

	HANDLE hThread1 = NULL;
	unsigned threadID1 = 0;

	hThread1 = (HANDLE)_beginthreadex(NULL, 0, threadFun1, NULL, 0, &threadID1);

	HANDLE hThread2 = NULL;
	unsigned threadID2 = 0;

	hThread2 = (HANDLE)_beginthreadex(NULL, 0, threadFun2, NULL, 0, &threadID2);

	while(1);

	return 0;
}
        編譯執行程式碼,結果如下: