线程同步之EVENT

事件可传信给其他线程,表示某些条件现在已具备,比如有可用的消息。

事件可分为手动复位和自动复位,前者可传信给许多同时等待事件的线程而且可以被复位。

自动复位的事件传信给单个等待时间的线程,该事件会自动复位。

Applications can use event objects in a number of situations to notify a waiting thread of the occurrence of an event. For example, overlapped I/O operations on files, named pipes, and communications devices use an event object to signal their completion. 

The following example(From MSDN)uses event objects to prevent several threads from reading from a shared memory buffer while a master thread is writing to that buffer. First, the master thread uses the CreateEvent function to create a manual-reset event object whose initial state is nonsignaled. Then it creates several reader threads. The master thread performs a write operation and then sets the event object to the signaled state when it has finished writing.

Before starting a read operation, each reader thread uses WaitForSingleObject to wait for the manual-reset event object to be signaled. When WaitForSingleObject returns, this indicates that the main thread is ready for it to begin its read operation.

#include 
   
   
    
    
#include 
    
    
     
     

#define THREADCOUNT 4

HANDLE ghWriteEvent;
HANDLE ghThreads[THREADCOUNT];

DWORD WINAPI ThreadProc(LPVOID);

void CreateEventsAndThreads(void)
{
    int i;
    DWORD dwThreadID;

    // Create a manual-reset event object. The write thread sets this
    // object to the signaled state when it finishes writing to a
    // shared buffer.

    ghWriteEvent = CreateEvent(
        NULL,               // default security attributes
        TRUE,               // manual-reset event
        FALSE,              // initial state is nonsignaled
        TEXT("WriteEvent")  // object name
        );

    if (ghWriteEvent == NULL)
    {
        printf("CreateEvent failed (%d)\n", GetLastError());
        return;
    }

    // Create multiple threads to read from the buffer.

    for(i = 0; i < THREADCOUNT; i++)
    {
        // TODO: More complex scenarios may require use of a parameter
        //   to the thread procedure, such as an event per thread to
        //   be used for synchronization.
        ghThreads[i] = CreateThread(
            NULL,              // default security
            0,                 // default stack size
            ThreadProc,        // name of the thread function
            NULL,              // no thread parameters
            0,                 // default startup flags
            &dwThreadID);

        if (ghThreads[i] == NULL)
        {
            printf("CreateThread failed (%d)\n", GetLastError());
            return;
        }
    }
}

void WriteToBuffer(VOID)
{
    // TODO: Write to the shared buffer.

    printf("Main thread writing to the shared buffer...\n");

    // Set ghWriteEvent to signaled

    if (! SetEvent(ghWriteEvent) )
    {
        printf("SetEvent failed (%d)\n", GetLastError());
        return;
    }
}

void CloseEvents()
{
    // Close all event handles (currently, only one global handle).

    CloseHandle(ghWriteEvent);
}

int main( void )
{
    DWORD dwWaitResult;

    // TODO: Create the shared buffer

    // Create events and THREADCOUNT threads to read from the buffer

    CreateEventsAndThreads();

    // At this point, the reader threads have started and are most
    // likely waiting for the global event to be signaled. However,
    // it is safe to write to the buffer because the event is a
    // manual-reset event.

    WriteToBuffer();

    printf("Main thread waiting for threads to exit...\n");

    // The handle for each thread is signaled when the thread is
    // terminated.
    dwWaitResult = WaitForMultipleObjects(
        THREADCOUNT,   // number of handles in array
        ghThreads,     // array of thread handles
        TRUE,          // wait until all are signaled
        INFINITE);

    switch (dwWaitResult)
    {
        // All thread objects were signaled
        case WAIT_OBJECT_0:
            printf("All threads ended, cleaning up for application exit...\n");
            break;

        // An error occurred
        default:
            printf("WaitForMultipleObjects failed (%d)\n", GetLastError());
            return 1;
    }

    // Close the events to clean up

    CloseEvents();

    return 0;
}

DWORD WINAPI ThreadProc(LPVOID lpParam)
{
    // lpParam not used in this example.
    UNREFERENCED_PARAMETER(lpParam);

    DWORD dwWaitResult;

    printf("Thread %d waiting for write event...\n", GetCurrentThreadId());

    dwWaitResult = WaitForSingleObject(
        ghWriteEvent, // event handle
        INFINITE);    // indefinite wait

    switch (dwWaitResult)
    {
        // Event object was signaled
        case WAIT_OBJECT_0:
            //
            // TODO: Read from the shared buffer
            //
            printf("Thread %d reading from buffer\n",
                   GetCurrentThreadId());
            break;

        // An error occurred
        default:
            printf("Wait error (%d)\n", GetLastError());
            return 0;
    }

    // Now that we are done reading the buffer, we could use another
    // event to signal that this thread is no longer reading. This
    // example simply uses the thread handle for synchronization (the
    // handle is signaled when the thread terminates.)

    printf("Thread %d exiting\n", GetCurrentThreadId());
    return 1;
}
/*Thread 4516 waiting for write event...
Thread 5156 waiting for write event...
Main thread writing to the shared buffer...
Main thread waiting for threads to exit...
Thread 5156 reading from buffer
Thread 5156 exiting
Thread 8824 waiting for write event...
Thread 8824 reading from buffer
Thread 4516 reading from buffer
Thread 8824 exiting
Thread 4516 exiting
Thread 11724 waiting for write event...
Thread 11724 reading from buffer
Thread 11724 exiting
All threads ended, cleaning up for application exit...

Process returned 0 (0x0)   execution time : 0.557 s
Press any key to continue.
*/

    
    
   
   


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值