秒杀多线程第六篇 经典线程同步 事件Event .
2013-04-16 13:58
246 查看
参考博客:/article/1358219.html
使用Event来解决线程同步问题,Event其实是一个内核对象,下面列出相关的操作函数
1.创建事件
HANDLECreateEvent(
LPSECURITY_ATTRIBUTESlpEventAttributes,
BOOLbManualReset,
BOOLbInitialState,
LPCTSTRlpName
);
第一个参数:表示安全按控制一般传入NULL
第二个参数:确定事件是手动设置还是自动设置
手动设置(TRUE):触发后允许所有线程执行,一直到关闭为止
自动设置(FALSE):触发一次允许一个线程执行
如果为自动置位,则对该事件调用WaitForSingleObject()后
会自动调用ResetEvent()使事件变成未触发状态。
第三个参数:表示事件的初始状态,传入TRUE表示事件被触发
第四个参数:表示事件的名称,传入NULL表示匿名事件
2.根据名称获得事件的句柄
HANDLEOpenEvent(
DWORDdwDesiredAccess,
BOOLbInheritHandle,
LPCTSTRlpName //名称
);
第一个参数:表示访问权限,对事件一般传入EVENT_ALL_ACCESS
第二个参数表示事件句柄继承性,一般传入TRUE即可。
第三个参数表示名称,不同进程中的各线程可以通过名称来确保它们访问同一个事件。
3.触发事件(必须有一个或者多个线程等待调度)
BOOLSetEvent(HANDLEhEvent);
4.将事件设为未触发状态
BOOLResetEvent(HANDLEhEvent);
4.事件的清理与销毁
CloseHandle();
运行结果:
结果发现线程号没有重复,且全局资源递增,说明主线程与子线程达到了同步,子线程之间形成了互斥
PulseEvent()来发出一个短暂的触发脉冲相当于同事调用
SetEvent(g_hThreadEvent);
ResetEvent(g_hThreadEvent);
使用Event来解决线程同步问题,Event其实是一个内核对象,下面列出相关的操作函数
1.创建事件
HANDLECreateEvent(
LPSECURITY_ATTRIBUTESlpEventAttributes,
BOOLbManualReset,
BOOLbInitialState,
LPCTSTRlpName
);
第一个参数:表示安全按控制一般传入NULL
第二个参数:确定事件是手动设置还是自动设置
手动设置(TRUE):触发后允许所有线程执行,一直到关闭为止
自动设置(FALSE):触发一次允许一个线程执行
如果为自动置位,则对该事件调用WaitForSingleObject()后
会自动调用ResetEvent()使事件变成未触发状态。
第三个参数:表示事件的初始状态,传入TRUE表示事件被触发
第四个参数:表示事件的名称,传入NULL表示匿名事件
2.根据名称获得事件的句柄
HANDLEOpenEvent(
DWORDdwDesiredAccess,
BOOLbInheritHandle,
LPCTSTRlpName //名称
);
第一个参数:表示访问权限,对事件一般传入EVENT_ALL_ACCESS
第二个参数表示事件句柄继承性,一般传入TRUE即可。
第三个参数表示名称,不同进程中的各线程可以通过名称来确保它们访问同一个事件。
3.触发事件(必须有一个或者多个线程等待调度)
BOOLSetEvent(HANDLEhEvent);
4.将事件设为未触发状态
BOOLResetEvent(HANDLEhEvent);
4.事件的清理与销毁
CloseHandle();
#include <stdio.h> #include <process.h> #include <windows.h> //定义事件句柄 HANDLE g_hThreadEvent; //关键段的定义 CRITICAL_SECTION g_csThreadCode; long g_num; //登录次数 unsigned int __stdcall Fun(void *pPM); //线程函数 const DWORD THREAD_NUM = 10;//启动线程数 unsigned int __stdcall Fun(void *pPM) { //由于创建线程是要一定的开销的,所以新线程并不能第一时间执行到这来 int nThreadNum = *(int *)pPM; //子线程获取参数 SetEvent(g_hThreadEvent);//3.事件被触发 Sleep(50);//some work should to do EnterCriticalSection(&g_csThreadCode);//进入子线程序号的关键区域 g_num++; //处理全局资源 Sleep(0);//some work should to do printf("线程编号为%d 全局资源值为%d\n", nThreadNum, g_num); LeaveCriticalSection(&g_csThreadCode); return 0; } int main() { printf(" CS的演示与Event\n"); g_num = 0; g_hThreadEvent=CreateEvent(NULL,FALSE,FALSE,NULL); //1.创建事件 //关键段的初始化 InitializeCriticalSection(&g_csThreadCode); HANDLE handle[THREAD_NUM]; int i=0; while (i<THREAD_NUM) { handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL); i++; WaitForSingleObject(g_hThreadEvent,INFINITE);//2.等待事件被触发 } WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE); CloseHandle(g_hThreadEvent);//5.销毁事件 //离开关键区域 LeaveCriticalSection(&g_csThreadCode); return 0; }
运行结果:
结果发现线程号没有重复,且全局资源递增,说明主线程与子线程达到了同步,子线程之间形成了互斥
PulseEvent()来发出一个短暂的触发脉冲相当于同事调用
SetEvent(g_hThreadEvent);
ResetEvent(g_hThreadEvent);
相关文章推荐
- 秒杀多线程第六篇 经典线程同步 事件Event .
- 秒杀多线程第六篇 经典线程同步 事件Event
- 秒杀多线程第六篇 经典线程同步 事件Event
- 秒杀多线程第六篇 经典线程同步 事件Event
- 秒杀多线程第六篇 经典线程同步 事件Event
- 【转】秒杀多线程第六篇 经典线程同步 事件Event
- 转--- 秒杀多线程第六篇 经典线程同步 事件Event
- 秒杀多线程第六篇---经典线程同步 事件Event
- 秒杀多线程第六篇 经典线程同步 事件Event
- 秒杀多线程第六篇 经典线程同步 事件Event
- 秒杀多线程第六篇 经典线程同步 事件Event
- 秒杀多线程第六篇 经典线程同步 事件Event
- 秒杀多线程第六篇 经典线程同步 事件Event
- 秒杀多线程第六篇 经典线程同步 事件Event
- 秒杀多线程第六篇 经典线程同步 事件Event
- 秒杀多线程第六篇 经典线程同步 事件Event
- 秒杀多线程第六篇 经典线程同步 事件Event
- 秒杀多线程第九篇 经典线程同步总结 关键段 事件 互斥量 信号量
- 秒杀多线程第九篇 经典线程同步总结 关键段 事件 互斥量 信号量
- 秒杀多线程第九篇 经典线程同步总结 关键段 事件 互斥量 信号量