Python 线程:Event.set() 真的会通知每个等待线程吗
如果我有一个 threading.Event
和以下两行代码:
event.set()
event.clear()
并且我有一些正在等待该事件的线程。
我的问题与调用 set()
方法时发生的情况有关:
- 我可以绝对确定所有等待线程都会收到通知吗? (即
Event.set()
“通知”线程) - 或者这两行执行得如此之快,以至于某些线程可能仍在等待? (即
Event.wait()
轮询事件的状态,该状态可能已经再次“清除”)
感谢您的回答!
If I have a threading.Event
and the following two lines of code:
event.set()
event.clear()
and I have some threads who are waiting for that event.
My question is related to what happens when calling the set()
method:
- Can I be ABSOLUTELY sure that all the waiting thread(s) will be notified? (i.e.
Event.set()
"notifies" the threads) - Or could it happen that those two lines are executed so quickly after each other, that some threads might still be waiting? (i.e.
Event.wait()
polls the event's state, which might be already "cleared" again)
Thanks for your answers!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在 Python 的内部,事件是通过
Condition()< 实现的/code>
对象。
调用
event.set()
方法时, 条件的notify_all()
被调用(拿到锁后一定要保证不被中断),那么所有线程都会收到通知(只有当所有线程都获得锁后才会释放锁)线程被通知),因此您可以确保所有线程都将有效地被通知。现在,在通知之后清除事件不是问题......直到您不想使用
event.is_set()
检查等待线程中的事件值,但您只需要这种检查是否等待超时。示例:
有效的伪代码:
可能无效的伪代码:
编辑: 在 python >= 2.7 中,您仍然可以等待超时事件并确定事件的状态:
In the internals of Python, an event is implemented with a
Condition()
object.When calling the
event.set()
method, thenotify_all()
of the condition is called (after getting the lock to be sure to be not interrupted), then all the threads receive the notification (the lock is released only when all the threads are notified), so you can be sure that all the threads will effectively be notified.Now, clearing the event just after the notification is not a problem.... until you do not want to check the event value in the waiting threads with an
event.is_set()
, but you only need this kind of check if you were waiting with a timeout.Examples :
pseudocode that works :
pseudocode that may not work :
Edited : in python >= 2.7 you can still wait for an event with a timeout and be sure of the state of the event :
验证事情是否按预期工作很容易(注意:这是 Python 2 代码,需要针对 Python 3 进行调整):
如果运行上面的脚本并且它终止,则一切都应该很好: -) 注意有一百个线程正在等待事件被设置;它立即被设置和清除;所有线程都应该看到这一点并且应该终止(尽管不是以任何明确的顺序,并且“All done”可以在“Press Enter”提示之后的任何地方打印,而不仅仅是在最后。
It's easy enough to verify that things work as expected (Note: this is Python 2 code, which will need adapting for Python 3):
If you run the above script and it terminates, all should be well :-) Notice that a hundred threads are waiting for the event to be set; it's set and cleared straight away; all threads should see this and should terminate (though not in any definite order, and the "All done" can be printed anywhere after the "Press enter" prompt, not just at the very end.
Python 3+
更容易检查它是否有效
Python 3+
It's easier to check that it works