多线程同步之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;
}
//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;
}
相关文章推荐
- 多线程编程(13) - 多线程同步之 Event (事件对象)
- 多线程编程(13) - 多线程同步之 Event (事件对象)
- C++多线程同步(采用事件对象Event)
- 多线程编程(2) - 多线程同步之 Event (事件对象)
- 多线程同步之 Event (事件对象)
- python多线程threading事件对象event实现线程阻塞及timer时间对象
- js的event.srcElement与event.target(触发事件对象)
- Dom对象事件注册和取消(addEventListener/attachEvent)
- event事件对象
- 韩顺平 javascript教学视频_学习笔记27_dom对象(window对象3.history.location.navigator.screen.event)_js事件驱动编程
- 让FireFox支持 window.event 全局事件对象
- JS - attachEvent() / addEventListener() 对象添加触发事件
- Windows进程同步之事件内核对象(Event)
- jQuery通过event获取点击事件的事件对象
- c++事件内核对象(event)进程间激活
- jquery笔记:事件对象 event.currentTarget,event.data,event.delegateTarget,event.relatedTarget.......
- 事件对象event 和ev
- 处理事件的方式:两种类的覆盖处理(自己管理,覆盖专用事件函数;自己统一管理,覆盖QWidget::Event通用函数),一种对象的处理(父控件统一管理,即安装过滤器),两种全局处理(QCoreApplication安装过滤器;覆盖notify方法)
- Dom对象事件注册和取消(addEventListener/attachEvent)
- Dojo学习--event(2): 事件指派和对象方法