事件相关函数:
1.创建事件:CreateEvent
HANDLE CreateEvent
(
LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset,
BOOL bInitialState,
LPCTSTR lpName
);
2.根据时间名称获得事件句柄:OpenEvent
HANDLE OpenEvent
(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCTSTR lpName
);
3.触发事件:SetEvent
BOOL SetEvent(HANDLE hEvent);
4.将事件设置为未触发:ResetEvent
BOOL ResetEvent(HANDLE hEvent);
5.将被触发后的事件立即设置为未触发:PulseEvent
BOOL PulseEvent(HANDLE hEvent);
使用事件机制解决线程同步问题测试代码:
#include <stdio.h>
#include <process.h>
#include <Windows.h>
#define THREAD_NUM 10
unsigned long g_nNum;
//事件与关键段
HANDLE g_hThreadEvent;
CRITICAL_SECTION g_csThreadCode;
unsigned int __stdcall ThreadFun(void *pM)
{
int nThreadNum = *(int *)pM;
//触发事件
SetEvent(g_hThreadEvent);
Sleep(50);
EnterCriticalSection(&g_csThreadCode);
g_nNum++;
Sleep(0);
printf("线程编号为%d 全局资源值为%d\n", nThreadNum, g_nNum);
LeaveCriticalSection(&g_csThreadCode);
return 0;
}
int main()
{
int i = 0;
HANDLE handle[THREAD_NUM];
printf("--------------------经典线程同步之事件--------------------\n");
//初始化事件和关键段, 自动置位,初始化无触发的匿名事件
g_hThreadEvent = CreateEvent(NULL, 0, 0, NULL);
InitializeCriticalSection(&g_csThreadCode);
g_nNum = 0;
while(i < THREAD_NUM)
{
handle[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun, &i, 0, NULL);
//等待事件被触发
WaitForSingleObject(g_hThreadEvent, INFINITE);
i++;
}
WaitForMultipleObjects(THREAD_NUM, handle, 1, INFINITE);
//销毁事件和关键段
CloseHandle(g_hThreadEvent);
DeleteCriticalSection(&g_csThreadCode);
system("pause");
return 0;
}
以上代码在Visual Studio 2010中的运行结果如下:
由此可见,使用事件机制和关键段,终于解决了线程同步与互斥的问题。