有段时间没有接触多线程相关的知识了,难免会遗忘或者生疏。多线程通信和同步相关的知识运用比较广,而且比较常见。今天通过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;
}
编译运行代码,结果如下: