版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/brunomarss/article/details/82984791
/*
* 说明:线程同步中Event对象的使用
* 特点:核心对象
* 目的:成为激发或未激发状态,两种状态完全由程序控制
* 执行状态:
* 1. 线程编号的输出没有重复,说明主线程与子线程达到了同步。
* 2. 全局资源的输出是递增的,说明各子线程已经互斥的访问和输出该全局资源。
*/
#include <stdio.h>
#include <process.h>
#include <windows.h>
#include <stdlib.h>
long g_nNum;
const int THREAD_NUM = 10;
// 事件和临界区
HANDLE g_hThreadEvent;
CRITICAL_SECTION g_csThreadCode;
unsigned int __stdcall Fun(void *pPM);
int main()
{
printf("线程同步-事件Event\n");
// 初始化事件
g_hThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
// 初始化临界区
InitializeCriticalSection(&g_csThreadCode);
HANDLE handle[THREAD_NUM];
g_nNum = 0;
int i = 0;
while (i<THREAD_NUM)
{
// 创建线程,等待事件触发
handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL);
WaitForSingleObject(g_hThreadEvent, INFINITE); // 等待事件被触发
i++;
}
// 主线程等待工作线程结束
WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);
// 销毁事件和临界区
CloseHandle(g_hThreadEvent);
DeleteCriticalSection(&g_csThreadCode);
system("pause");
return 0;
}
unsigned int __stdcall Fun(void *pPM)
{
int nThreadNum = *(int *)pPM;
SetEvent(g_hThreadEvent); // 触发事件,触发后必定有一个或多个线程处于可执行状态
Sleep(50); // 做点什么
EnterCriticalSection(&g_csThreadCode);
g_nNum++;
Sleep(0); // 做点什么
printf("线程编号为%d 全局资源值为%d\n", nThreadNum, g_nNum);
LeaveCriticalSection(&g_csThreadCode);
return 0;
}