我可以使用线程模块中的 Event 对象,不仅可以通知某些事件已经发生,而且还可以提供该事件的一些参数,例如:
e = Event()
...
e.param = "this is event data"
e.set()
另一个线程:
e.wait()
data = e.param
乍一看似乎没问题,但有什么问题不能发生吗?安全吗?如果不是,还有什么其他方式可以更好地在线程之间传递一些事件参数?
谢谢。
我可以使用线程模块中的 Event 对象,不仅可以通知某些事件已经发生,而且还可以提供该事件的一些参数,例如:
e = Event()
...
e.param = "this is event data"
e.set()
另一个线程:
e.wait()
data = e.param
乍一看似乎没问题,但有什么问题不能发生吗?安全吗?如果不是,还有什么其他方式可以更好地在线程之间传递一些事件参数?
谢谢。
您实际上不需要将值附加到Event
对象,您可以使用与 分开的其他一些全局、属性等Event
,并使用Event
来表示它已被更新。这是通常的做事方式。
但你的所作所为真的没有错。除了使用事件发出信号的常见比赛问题之外,它不会增加任何其他问题。然而,它看起来确实有点误导——它看起来好像param
是同步的,但实际上并非如此。
如果您试图表明一个新值已准备就绪,并同步访问该值,您几乎总是需要一个Condition
,如下所示:
c = Condition()
data = None
...
with c:
data = "new data"
c.notify()
...
with c:
while data is None:
c.wait()
或者,更简单地说,只使用 aqueue
并且一开始不共享变量:
q = Queue()
...
q.put(data)
...
data = q.get()
这种方法的一个潜在问题是,如果事件被快速设置,则在等待线程读取旧值之前可能会覆盖参数。
这种线程间消息传递的更标准方法是使用Queue.Queue
. 但是,基于队列的解决方案的限制是只有一个线程可以读取消息。换句话说:读者消费信息。这种方法非常适合生产者-消费者范式。(您没有提到是否有多个线程在等待事件)。
对于多个阅读器线程,您还应该考虑pubsub(发布者/订阅者)解决方案,尽管我不知道 python 中有任何开箱即用的 pubsub 实现。