Can a single SetEvent() trigger multiple WaitForSingleObject()

前端 未结 4 1975
一向
一向 2021-02-09 00:35

This:

http://msdn.microsoft.com/en-us/library/ms686915(VS.85).aspx

Would seem to suggest not.

I have three processes communicating via pipes. Process A C

相关标签:
4条回答
  • 2021-02-09 00:44

    You can use the Manual Reset Events and the PulseEvent function to release all of the threads currently waiting for the event.

    Note however, that this approach is inherently racy, as there is no way to tell which are "the threads currently waiting ...". You should use a more reliable synchronization mechanism if exact matching of the wakeup/2 wait events are needed.

    0 讨论(0)
  • 2021-02-09 00:51

    One event can notify multiple threads if it is a manual-reset event. An auto-reset event cannot do that. If more than one tread is waiting simultaneously for an auto-reset event, and you set it to the signaled state, only one thread exists and resets it, and the behavior of the other threads will be undefined. Although, from the Microsoft documentation, we may assume that one and only one thread will exit while others would definitely not exit. Anyway, we must take the following quote into consideration: “Do not assume a first-in, first-out (FIFO) order. External events such as kernel-mode APCs can change the wait order” Source - https://msdn.microsoft.com/en-us/library/windows/desktop/ms682655(v=vs.85).aspx

    The CreateEvent function has the bManualReset parameter. If it is TRUE, the function creates a manual-reset event object, which requires the use of the ResetEvent function to set the event state to non-signaled. If this parameter is FALSE, the function creates an auto-reset event object, and system automatically resets the event state to non-signaled after a single waiting thread has been released, i.e. has exited from a function like WaitForMultipleObjects or WaitForSigleObject – but, as I wrote before, only one thread will be notified not all.

    As about the PulseEvent – it is unreliable and should never be used -- see https://msdn.microsoft.com/en-us/library/windows/desktop/ms684914(v=vs.85).aspx

    Only those threads are notified by PulseEvent that are in the "wait" state at the moment PulseEvent is called. If they are in any other state, they will not be notified, and you may never know for sure what the thread state is. A thread waiting on a synchronization object can be momentarily removed from the wait state by a kernel-mode Asynchronous Procedure Call, and then returned to the wait state after the APC is complete. If the call to PulseEvent occurs during the time when the thread has been removed from the wait state, the thread will not be released because PulseEvent releases only those threads that are waiting at the moment it is called. You can find out more about the kernel-mode Asynchronous Procedure Calls (APC) at the following links:

    • https://msdn.microsoft.com/en-us/library/windows/desktop/ms681951(v=vs.85).aspx
    • http://www.drdobbs.com/inside-nts-asynchronous-procedure-call/184416590
    • http://www.osronline.com/article.cfm?id=75

    You can get more ideas about auto-reset events and manual reset events from the following article:

    • https://www.codeproject.com/Articles/39040/Auto-and-Manual-Reset-Events-Revisited
    0 讨论(0)
  • 2021-02-09 01:01

    Use manual reset events to trigger multiple threads off of a single event.

    Here is an example which uses "Manual Reset Event" flag

    0 讨论(0)
  • 2021-02-09 01:04

    I hope this example can help you:

    handle1A = CreateEvent(LPSECURITY_ATTRIBUTES, ManualReset, InitialState, NAME)
    
    handle1B = CreateEvent(LPSECURITY_ATTRIBUTES, ManualReset, InitialState, NAME)
    
    handle2A = CreateEvent(LPSECURITY_ATTRIBUTES, ManualReset, InitialState, NAME+GetCurrentThreadId())
    
    handle2B = CreateEvent(LPSECURITY_ATTRIBUTES, ManualReset, InitialState, NAME+GetCurrentThreadId())
    

    A) if you create a event with the same NAME, every setEvent signaling all waitforsingleobjects

    SetEvent(handle1A) // Send signaling to handle1A and handle1B
    

    B) if you create a event whith a unique NAME, the setEvent only sends the signal to referenced handle

    SetEvent(handle2) // Send signling only to handle2A. The Id Thread is unique
    
    0 讨论(0)
提交回复
热议问题