问题 Windows中的Mutex vs Event


如果我这样做,请有人解释一下有什么区别

mutex = createMutex
waitForSingleObject
Release(mutex)

event = createEvent
waitForSingleObject
Release(event)

我很困惑,我可以使用两个版本进行同步吗?提前感谢您的帮助


940
2017-08-02 14:12


起源



答案:


您使用互斥锁来确保只有一个执行线程可以访问某些内容。例如,如果要更新可能由多个线程使用的列表,则使用互斥锁:

acquire mutex
update list
release mutex

使用互斥锁,一次只能有一个线程执行“更新列表”。

如果您希望多个线程在继续之前等待某些事情发生,则使用手动重置事件。例如,您启动了多个线程,但在它们可以继续之前,它们都会暂停等待其他事件。一旦该事件发生,所有线程都可以开始运行。

主线程看起来像这样:

create event, initial value false (not signaled)
start threads
do some other initialization
signal event

每个线程的代码都是:

do thread initialization
wait for event to be signaled
do thread processing

12
2017-08-02 14:40



互斥锁的初始值是什么:发信号或未发信号? - yeap
@yeap:在几乎所有情况下,包括这个,你都想创建互斥锁,这样它最初就不会被获取。 - Jim Mischel
一个重要的区别是互斥锁可以被同一个线程重复锁定(它是“递归的”),而事件可以用来实现非递归锁定。 - Frerich Raabe
如果在我没有等待它时触发了Event会怎么样,但是一旦我准备好它就不会被触发(例如,init ready事件) - Johnny_D
@Johnny_D:如果设置了手动重置事件,它将保持设置直到重置为止。因此,在您的情况下,事件已设置,另一个线程出现并看到它已设置,并且只是继续 - 无需等待。如果您对事件的工作方式有进一步的疑问,请发布问题而不是在此处发表评论。 - Jim Mischel


答案:


您使用互斥锁来确保只有一个执行线程可以访问某些内容。例如,如果要更新可能由多个线程使用的列表,则使用互斥锁:

acquire mutex
update list
release mutex

使用互斥锁,一次只能有一个线程执行“更新列表”。

如果您希望多个线程在继续之前等待某些事情发生,则使用手动重置事件。例如,您启动了多个线程,但在它们可以继续之前,它们都会暂停等待其他事件。一旦该事件发生,所有线程都可以开始运行。

主线程看起来像这样:

create event, initial value false (not signaled)
start threads
do some other initialization
signal event

每个线程的代码都是:

do thread initialization
wait for event to be signaled
do thread processing

12
2017-08-02 14:40



互斥锁的初始值是什么:发信号或未发信号? - yeap
@yeap:在几乎所有情况下,包括这个,你都想创建互斥锁,这样它最初就不会被获取。 - Jim Mischel
一个重要的区别是互斥锁可以被同一个线程重复锁定(它是“递归的”),而事件可以用来实现非递归锁定。 - Frerich Raabe
如果在我没有等待它时触发了Event会怎么样,但是一旦我准备好它就不会被触发(例如,init ready事件) - Johnny_D
@Johnny_D:如果设置了手动重置事件,它将保持设置直到重置为止。因此,在您的情况下,事件已设置,另一个线程出现并看到它已设置,并且只是继续 - 无需等待。如果您对事件的工作方式有进一步的疑问,请发布问题而不是在此处发表评论。 - Jim Mischel


是的,两者都可以用于同步,但方式不同。

互斥 是一个互斥对象,一次只能由一个实例获取。它用于避免通过计算机代码片段同时使用公共资源,例如全局变量

事件 是一个可以通过使用SetEvent函数显式设置为状态的对象。


1
2017-08-02 14:17



你的意思是什么?可以通过多个实例获取事件?如果我执行waitForSingleObject,也可以发信号通知mutex,我错了吗? - yeap
是的,事实上任何同步对象都可以在WaitForSingleObject / WaitForMultipleObject中使用。不同之处在于他的行为。 - cprogrammer
不会像获取互斥锁或关键部分那样获取事件。事件发生时可以发出事件信号。 - cprogrammer
多个实例怎么样?多个实例可以等待某些信号吗? - yeap
是。任何数量的实例都可以等待 - cprogrammer