Windows Win32事件对象是递归互斥体吗?

Windows Win32事件对象是递归互斥体吗?,windows,multithreading,locking,mutex,deadlock,Windows,Multithreading,Locking,Mutex,Deadlock,我搜索了MSDN,互斥可以被锁定两次,但是在同一个线程中,递归获取同一事件对象两次没有任何单词 我们可以在同一个线程中锁定win32事件两次吗 编辑:锁定事件的含义是什么?这里我假设事件是自动重置的 锁定:从WaitForXXX(例如WaitForSingleObject)唤醒线程 解除锁定:线程正在调用SetEvent或PluseEvent 互斥从根本上讲与事件不同。互斥锁用于提供互斥,因此一次只能有一个线程访问资源,而事件只是一种通知机制。自动重置事件提供单个唤醒通知,而手动重置事件提供多个

我搜索了MSDN,互斥可以被锁定两次,但是在同一个线程中,递归获取同一事件对象两次没有任何单词

我们可以在同一个线程中锁定win32事件两次吗

编辑:锁定事件的含义是什么?这里我假设事件是自动重置的

  • 锁定:从WaitForXXX(例如WaitForSingleObject)唤醒线程
  • 解除锁定:线程正在调用SetEvent或PluseEvent

  • 互斥从根本上讲与事件不同。互斥锁用于提供互斥,因此一次只能有一个线程访问资源,而事件只是一种通知机制。自动重置事件提供单个唤醒通知,而手动重置事件提供多个唤醒通知

    如果发出自动重置事件的信号,则只有一个线程将接收该信号,并且该线程只接收一次;任何其他线程——或来自同一线程对该事件的等待函数的任何其他调用——都将等待,直到第二次调用
    SetEvent

    如果您向手动重置事件发送信号,那么它将一直处于信号状态,直到您重置它为止,因此多个线程可以唤醒,并且在某些线程调用
    ResetEvent
    之前,同一线程对该事件的等待函数的多次调用将成功

    无论哪种方式,事件都没有“所有者”:仅仅因为线程A上次被另一个设置事件的线程从其对等待函数的调用中唤醒,没有任何东西可以阻止它再次等待,也没有任何东西可以指定如果线程A或线程B都在同一个自动重置事件上等待,那么线程A或线程B是否会被唤醒。也不需要任何特定线程调用
    SetEvent
    :系统中的任何线程都可以这样做,无论该线程是否调用该事件的等待函数。实际上,一个常见用例有一个线程调用SetEvent,一个或多个其他线程等待

    因此:是的,您可以等待刚刚等待该事件的线程发出的事件,但这不是一个锁,其他线程也可能等待该事件,并且在发出事件信号时也可能会唤醒该事件

    已编辑问题的更新:

    您可以使用事件提供锁,但这不是固有语义的一部分。您可以使用相同的自动重置事件句柄连续调用两次WaitForSingleObject。就Windows而言,这不是一个错误:您只需要确保其他一些线程调用
    SetEvent
    两次,这样等待的线程就可以在第二次调用
    SetEvent
    之前从第一次调用
    WaitForSingleObject
    唤醒,以避免“丢失”唤醒:
    SetEvent
    不计算呼叫数,它只设置标志


    另外:不要使用
    PulseEvent
    。它不能保证线程会被唤醒,即使有一个线程正在等待。

    我同意安东尼·威廉姆斯的观点

    我想补充的一点是,许多人(不仅仅是你)不太理解互斥和自动重置事件之间的区别。实际上,它们的行为类似,并且可以(从技术角度)用于资源锁定

    它们之间的主要区别在于互斥体“知道”哪个线程持有它。也就是说,当
    WaitForSingleObject
    (或类似)获取互斥锁时,它会自动“分配”给调用线程。这有两个后果:

  • 互斥可以由同一线程递归获取。当然,这在自动重置事件中不起作用
  • 如果拥有互斥体的线程退出-互斥体将自动“释放”。相应的
    WaitXXXX
    函数将返回
    WAIT\u
  • 事件OTOH可以看作是信号量的特殊情况。自动重置事件相当于(最多)1充电的信号量,手动重置事件-相当于无限充电的信号量。

    Win32事件不能“锁定”。你说一个互斥锁可以被锁定两次是什么意思?