用内核对象进行线程同步——事件内核对象
来源:互联网 发布:linux创建多层文件夹 编辑:程序博客网 时间:2024/06/05 22:57
事件内核对象
1. 手动重置事件:当一个手动重置事件被触发的时候,所有等待该事件的线程都变为可调度状态。所以要注意此时所有的线程都只能以只读的方式来访问内存,这也是多个线程能够同时运行的唯一原因
2. 自动重置事件:当一个自动重置事件被触发的时候,只有一个等待该事件的线程都变为可调度状态(当线程成功等到事件触发的时候,会自动的把事件重置为未触发状态),其余的继续等待。
创建一个事件内核对象
HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, //TRUE:手动重置事件; FALSE:自动重置事件 BOOL bInitialState, //TRUE:事件初始化为触发状态; FALSE:事件初始化为未触发状态 LPCSTR lpName );
打开一个事件内核对象
其他进程中的线程要访问该事件对象可以调用OpenEvent
HANDLE OpenEvent( DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName );
改变事件触发状态
BOOL SetEvent(HANDLE hEvent); // 把事件变为触发状态BOOL ResetEvent(HANDLE hEvent); // 把事件变为未触发状态
关闭事件对象
当不在需要事件对象时,要调用CloseHandle来将它关闭
BOOL CloseHandle(HANDLE hObject);
手动重置事件例子
#include "stdafx.h"#include <windows.h>#include <process.h>#include <iostream>using namespace std;int g_x = 0;HANDLE g_hEvent;// 线程只读UINT WINAPI ThreadFunc1(PVOID pArguments){ WaitForSingleObject(g_hEvent, INFINITE); cout << "ThreadFunc1.." << endl; _endthreadex(0); return 0;}// 线程只读UINT WINAPI ThreadFunc2(PVOID pArguments){ WaitForSingleObject(g_hEvent, INFINITE); cout << "ThreadFunc2.." << endl; _endthreadex(0); return 0;}// 线程只读UINT WINAPI ThreadFunc3(PVOID pArguments){ WaitForSingleObject(g_hEvent, INFINITE); cout << "ThreadFunc3.." << endl; _endthreadex(0); return 0;}int _tmain(int argc, _TCHAR* argv[]){ HANDLE handle[3]; unsigned unThreadID[3]; cout << "g_x initial value: " << g_x << endl; // 创建一个未触发的手动重置事件 g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); handle[0] = (HANDLE)_beginthreadex(NULL, 0, &ThreadFunc1, NULL, 0, &unThreadID[0]); handle[1] = (HANDLE)_beginthreadex(NULL, 0, &ThreadFunc2, NULL, 0, &unThreadID[1]); handle[2] = (HANDLE)_beginthreadex(NULL, 0, &ThreadFunc3, NULL, 0, &unThreadID[2]); g_x = 100; // 给g_x赋值后调用SetEvent触发事件,此时三个线程都变成可调度状态,获得CPU时间。 // 但是注意此时所有的三个线程都只能以只读的方式来访问内存,这也是三个线程能够同时运行的唯一原因 SetEvent(g_hEvent); WaitForMultipleObjects(3, handle, TRUE, INFINITE); CloseHandle(g_hEvent); g_hEvent = NULL; cout << "g_x Final value: " << g_x << endl; getchar(); return 0;}
自动重置事件例子
// ThreadDemo.cpp : コンソール アプリケーションのエントリ ポイントを定義します。//#include "stdafx.h"#include <windows.h> #include <process.h> #include <iostream>using namespace std;int g_x = 0;HANDLE g_hEvent;// 写入线程UINT WINAPI ThreadFunc1(PVOID pArguments){ // 当线程成功等到事件对象触发的时候,自动重置事件会把事件对象重置为为触发状态,锁定资源,独占内存 WaitForSingleObject(g_hEvent, INFINITE); int n = 0; while (n < 5) { g_x += n; n++; cout << "ThreadFunc1.." << endl; } // 当线程结束,要释放资源,故把事件对象重置为触发状态,以便等待该资源的其他线程访问 SetEvent(g_hEvent); _endthreadex(0); return 0;}// 读线程UINT WINAPI ThreadFunc2(PVOID pArguments){ WaitForSingleObject(g_hEvent, INFINITE); cout << "ThreadFunc2.." << endl; SetEvent(g_hEvent); _endthreadex(0); return 0;}// 写入线程UINT WINAPI ThreadFunc3(PVOID pArguments){ WaitForSingleObject(g_hEvent, INFINITE); int n = 0; while (n < 5) { g_x += n; n++; cout << "ThreadFunc3.." << endl; } SetEvent(g_hEvent); _endthreadex(0); return 0;}int _tmain(int argc, _TCHAR* argv[]){ HANDLE handle[3]; unsigned unThreadID[3]; cout << "g_x initial value: " << g_x << endl; // 创建一个未触发的自动动重置事件 g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); handle[0] = (HANDLE)_beginthreadex(NULL, 0, &ThreadFunc1, NULL, 0, &unThreadID[0]); handle[1] = (HANDLE)_beginthreadex(NULL, 0, &ThreadFunc2, NULL, 0, &unThreadID[1]); handle[2] = (HANDLE)_beginthreadex(NULL, 0, &ThreadFunc3, NULL, 0, &unThreadID[2]); g_x = 100; // 由于事件初始化为未触发状态,所以在线程准备完毕后,调用SetEvent触发事件,此时只有一个线程都变成可调度状态,独占资源。其他线程继续等待 // 由于等待自动重置事件对象的线程是独占资源,故这些线程可读可写 SetEvent(g_hEvent); WaitForMultipleObjects(3, handle, TRUE, INFINITE); CloseHandle(g_hEvent); g_hEvent = NULL; cout << "g_x Final value: " << g_x << endl; getchar(); return 0;}
阅读全文
0 0
- 用内核对象进行线程同步——事件内核对象
- -【内核对象线程同步】事件内核对象
- 用内核对象进行线程同步——互斥量内核对象
- 用内核对象进行线程同步——信号量内核对象
- 线程同步--事件内核对象
- 用内核对象进行线程同步1
- windows 用内核对象进行线程同步
- 用内核对象进行线程同步
- 用内核对象进行线程同步
- Windows-核心编程-09-如何用内核对象进行线程同步-事件内核对象
- <<Windows核心编程(第五版)>>第九章用内核对象进行线程同步:9.3事件内核对象
- windows笔记-【内核对象线程同步】事件内核对象
- windows笔记-【内核对象线程同步】事件内核对象
- 用内核对象同步线程
- 线程与事件内核对象的同步
- 线程同步 事件 Event 内核对象 CreateEvent
- 内核对象和线程同步—WaitForSingleObject
- Windows Via C/C++:内核模式下的线程同步——事件内核对象
- php 获取父类或者子类名
- Centos Vim C/C++ IDE打造
- Qt5.4下连接Mysql,QSqlDatabase: QMYSQL driver not loaded but available
- 线程的几种状态转换
- hdu--6090--Rikka with Graph
- 用内核对象进行线程同步——事件内核对象
- synchronized使用方法
- 线程
- list集合对于基本数据类型与引用数据类型(对象)去重操作
- POJ 2196
- angularjs的MVC模式
- Codevs 1391 伊吹萃香/虫洞
- 螺旋矩阵(队列)
- Tp5关于include模版标签的使用和模版缓存问题