您的位置:首页 > 其它

多线程同步之Event(事件对象)

2012-11-08 17:04 232 查看
//多线程同步

//Event的应用

#define WIN32_LEAN_AND_MEAN

#include <STDIO.H>

#include <stdlib.h>

#include <WINDOWS.H>

#include "MtVerify.h"

//①创建Event事件句柄

HANDLE Auto_hEvent,Manual_hEvent;  //Auto类型的事件句柄,Manual类型的事件句柄

HANDLE hThread1,hThread2,hThread3;  //6个线程句柄

HANDLE hThread4,hThread5,hThread6;

DWORD ThreadId1,ThreadId2,ThreadId3; //6个线程的线程ID

DWORD ThreadId4,ThreadId5,ThreadId6; 

DWORD ExitCode1,ExitCode2,ExitCode3; //6个线程的线程退出码

DWORD ExitCode4,ExitCode5,ExitCode6;

DWORD WINAPI ThreadFunc1(LPVOID);  //线程函数1的定义

DWORD WINAPI ThreadFunc2(LPVOID);  //线程函数2的定义

int main()

{

 //②创建Event对象
 //AutoEvent表示event变成激发状态之后,自动重置为非激发状态

 //但不能自动的从非激发状态变成激发状态,这个是由程序自行操作的SetEvent

 MTVERIFY(Auto_hEvent = CreateEvent(

  NULL,     //默认安全属性

  FALSE,     //若FALSE,表示event变成激发状态之后,自动重置为非激发状态。若是TRUE表示不会自动重置

  FALSE,     //若TRUE,表示一开始处于激发状态,如为FALSE则表示一开始处于非激发状态

  "AutoEventName"   //Event对象名称,任何线程或进程都可以根据这个文字名称使用这个event对象

  ));

 //ManualEvent表示event变成激发状态之后,不会自动重置为非激发状态,

 //必须调用ResetEvent函数使其重置为非激发状态

 //同AutoEvent一样,也不能自动从非激发状态变成激发状态,必须调用SetEvent才能从非激发状态转变为激发状态

 MTVERIFY(Manual_hEvent = CreateEvent(NULL,TRUE,FALSE,"ManualEventName"));

 

 //创建6个线程

 MTVERIFY(hThread1 = CreateThread(NULL,0,ThreadFunc1,(LPVOID)1,NULL,&ThreadId1));

 MTVERIFY(hThread2 = CreateThread(NULL,0,ThreadFunc1,(LPVOID)2,NULL,&ThreadId2));

 MTVERIFY(hThread3 = CreateThread(NULL,0,ThreadFunc1,(LPVOID)3,NULL,&ThreadId3));

 MTVERIFY(hThread4 = CreateThread(NULL,0,ThreadFunc2,(LPVOID)4,NULL,&ThreadId4));

 MTVERIFY(hThread5 = CreateThread(NULL,0,ThreadFunc2,(LPVOID)5,NULL,&ThreadId5));

 MTVERIFY(hThread6 = CreateThread(NULL,0,ThreadFunc2,(LPVOID)6,NULL,&ThreadId6));

 //③设置Event为激发状态
 //因为在创建Event对象时,设定为创建非激发状态的事件对象

 //若想让等待这些事件对象的线程有机会执行,先要把事件对象设为激发状态

 SetEvent(Manual_hEvent); //设置为激发状态

 SetEvent(Auto_hEvent);  //设置为激发状态

 //若Event对象为ManualEvent(手动重置事件对象)

 //PulseEvent把Event对象设为激发状态

 //唤醒所有等待此Event对象的线程

// PulseEvent(Manual_hEvent);

 //若Event对象为AutoEvent(自动重置事件对象)

 //PulseEvent把Event对象设为激发状态

 //唤醒“一个”等待此Event对象的线程

// PulseEvent(Auto_hEvent);

 //获取6个线程的退出码

 GetExitCodeThread(hThread1,&ExitCode1);

 GetExitCodeThread(hThread2,&ExitCode2);

 GetExitCodeThread(hThread3,&ExitCode3);

 GetExitCodeThread(hThread4,&ExitCode4);

 GetExitCodeThread(hThread5,&ExitCode5);

 GetExitCodeThread(hThread6,&ExitCode6);

 //休眠2s等待线程执行结束

 Sleep(2000);

 //分别打印6个线程的退出码与线程ID

 printf("线程1的退出码:%ld,线程ID:%ld\n",ExitCode1,ThreadId1);

 printf("线程2的退出码:%ld,线程ID:%ld\n",ExitCode2,ThreadId2);

 printf("线程3的退出码:%ld,线程ID:%ld\n",ExitCode3,ThreadId3);

 printf("线程4的退出码:%ld,线程ID:%ld\n",ExitCode4,ThreadId4);

 printf("线程5的退出码:%ld,线程ID:%ld\n",ExitCode5,ThreadId5);

 printf("线程6的退出码:%ld,线程ID:%ld\n",ExitCode6,ThreadId6);

 

 //关闭与句柄的关联

 MTVERIFY(CloseHandle(hThread6));

 MTVERIFY(CloseHandle(hThread5));

 MTVERIFY(CloseHandle(hThread4));

 MTVERIFY(CloseHandle(hThread3));

 MTVERIFY(CloseHandle(hThread2));

 MTVERIFY(CloseHandle(hThread1));
 //⑥关闭与Event的关联
 MTVERIFY(CloseHandle(Auto_hEvent));

 MTVERIFY(CloseHandle(Manual_hEvent));

 return 0;

}

DWORD WINAPI ThreadFunc1(LPVOID n)//线程函数1的实现

{
 //④等待Event激发
 //等待激发的Event<事件>对象

 WaitForSingleObject(Auto_hEvent,INFINITE);

 printf("线程%ld正在运行\n",(int)n);

 //⑤手动设置Event为激发
 //激发的一个线程会自动设置为非激发状态

 //若想让其他等待这个事件对象的线程能继续执行

 //需要先把这个事件对象设置激发状态

 SetEvent(Auto_hEvent); //设置为激发状态

 return (DWORD)n;

}

DWORD WINAPI ThreadFunc2(LPVOID n)//线程函数2的实现

{

 //等待激发的Event<事件>对象

 WaitForSingleObject(Manual_hEvent,INFINITE);

 printf("线程%ld正在运行\n",(int)n);

 //激发的一个线程不会自动设置为非激发状态

 //必须手动通过函数来设置其非激发状态

 //这个事件对象设置为非激发状态后,并没有设置为激发状态

 //所以线程 4,5,6只可能会有一个线程能获得这个事件的激发

 //状态并执行下去

 ResetEvent(Manual_hEvent);

 return (DWORD)n;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息