利用事件对象实现线程同步

事件对象也属于内核对象,包含一个使用计数,一个用于指明该事件是一个自动重置事件还是人工重置事件的bool值,另一个用于指明该事件处于已通知状态(有信号状态)还是未通知状态(无信号状态)的bool值,当人工重置的事件得到通知时,等待该事件的所有线程均变为可调度线程,需要用ResetEvent函数设置其事件状态,且WaitForSingleObject不能设置该事件对象的状态。当一个自动重置的事件得到通知时,等待该事件的线程中只有一个线程变为可调度线程,WaitForSingleObject将自动设置该事件对象的状态。

bManualReset
[in] Specifies whether a manual-reset or auto-reset event object is created. If TRUE, then you must use the ResetEvent function to manually reset the state to nonsignaled. If FALSE, the system automatically resets the state to nonsignaled after a single waiting thread has been released.

#include <windows.h>
#include <iostream.h>

DWORD WINAPI Func1Proc(LPVOID lpParameter);
DWORD WINAPI Func2Proc(LPVOID lpParameter);

int tickets = 100;
HANDLE g_hEvent;

int main()
{
    HANDLE hThread1;
    HANDLE hThread2;
    hThread1 = CreateThread(NULL, 0, Func1Proc, NULL, 0, NULL);
    hThread2 = CreateThread(NULL, 0, Func2Proc, NULL, 0, NULL);
    CloseHandle(hThread1);
    CloseHandle(hThread2);
    g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);//创建一个自动重置、无信号状态的事件对象
    SetEvent(g_hEvent);
    Sleep(4000);
    CloseHandle(g_hEvent);
    return 0;
}

DWORD WINAPI Func1Proc(LPVOID lpParameter)
{
    while (TRUE)
    {
        WaitForSingleObject(g_hEvent, INFINITE);//该事件对象被设置为无信号状态,进入互斥区
        if (tickets > 0)
        {
            Sleep(1);
            cout<<"Thread1 sell ticket:"<<tickets--<<endl;
        }
        else
        {
            break;
        }
        SetEvent(g_hEvent);//该事件对象被设置为有信号状态,退出互斥区
    }
    return 0;
}

DWORD WINAPI Func2Proc(LPVOID lpParameter)
{
    while (TRUE)
    {
        WaitForSingleObject(g_hEvent, INFINITE);
        if (tickets > 0)
        {   
            Sleep(1);
            cout<<"Thread2 sell ticket:"<<tickets--<<endl;
        }
        else
        {
            break;
        }
        SetEvent(g_hEvent);
    }
    return 0;

你可能感兴趣的:(thread,function,object,null,System,winapi)