Windows Win32事件对象是递归互斥体吗?
我搜索了MSDN,互斥可以被锁定两次,但是在同一个线程中,递归获取同一事件对象两次没有任何单词 我们可以在同一个线程中锁定win32事件两次吗 编辑:锁定事件的含义是什么?这里我假设事件是自动重置的Windows Win32事件对象是递归互斥体吗?,windows,multithreading,locking,mutex,deadlock,Windows,Multithreading,Locking,Mutex,Deadlock,我搜索了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