网上的资料基本都是java实现的,c++的很少,加上win32的API函数对我个人而言晦涩难懂,真是举步维艰~
目前而言对我来说最好理解的,最简单的,是使用Event。
首先明白Event的用法:秒杀多线程第六篇 经典线程同步 事件Event
CreateEvent
函数功能:创建事件
//函数原型:
HANDLECreateEvent(
LPSECURITY_ATTRIBUTESlpEventAttributes,
BOOLbManualReset,
BOOLbInitialState,
LPCTSTRlpName
);
函数说明:
- 第一个参数表示安全控制,一般直接传入NULL。
- 第二个参数确定事件是手动置位还是自动置位,传入TRUE表示手动置位,传入FALSE表示自动置位。如果为自动置位,则对该事件调用WaitForSingleObject()后会自动调用ResetEvent()使事件变成未触发状态。打个小小比方,手动置位事件相当于教室门,教室门一旦打开(被触发),所以有人都可以进入直到老师去关上教室门(事件变成未触发)。自动置位事件就相当于医院里拍X光的房间门,门打开后只能进入一个人,这个人进去后会将门关上,其它人不能进入除非门重新被打开(事件重新被触发)。
(此中有坑)- 第三个参数表示事件的初始状态,传入TRUR表示已触发。
- 第四个参数表示事件的名称,传入NULL表示匿名事件。
SetEvent
函数功能:触发事件
函数原型:BOOLSetEvent(HANDLEhEvent);
函数说明:每次触发后,必有一个或多个处于等待状态下的线程变成可调度状态。
ResetEvent
函数功能:将事件设为末触发
函数原型:BOOLResetEvent(HANDLEhEvent);
最简单的实现是,先分别创建三个线程分别打印对应次数的字母A/B/C,还有三个事件event ,其中每个线程在打印的时候使用waitforsingleobject来阻塞,只有wait到了对应的事件,才可以输出对应的字母,然后打印完毕后,用setevent把下一个事件触发,然后执行下一个事件。
最简单的代码:
using namespace std;
const int NUM = 3;
int nCount = 1; //用来表示先打印哪一个 0-A,1-B,2-C
HANDLE g_Event[NUM] = { NULL };//三个事件
unsigned int WINAPI funA(LPVOID pM)
{
for (int i = 0; i < 100; i++)
{
WaitForSingleObject(g_Event[0], INFINITE); //等待g_Event[0],然后才执行打印A;
cout << 'A';
Sleep(100);
nCount ++ ;
SetEvent(g_Event[(nCount) % NUM]);
}
return