6

我可以使用线程模块中的 Event 对象,不仅可以通知某些事件已经发生,而且还可以提供该事件的一些参数,例如:

e = Event()
...
e.param = "this is event data"
e.set()

另一个线程:

e.wait()
data = e.param

乍一看似乎没问题,但有什么问题不能发生吗?安全吗?如果不是,还有什么其他方式可以更好地在线程之间传递一些事件参数?

谢谢。

4

2 回答 2

5

您实际上不需要将值附加到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()
于 2013-10-02T20:55:40.160 回答
1

这种方法的一个潜在问题是,如果事件被快速设置,则在等待线程读取旧值之前可能会覆盖参数。

这种线程间消息传递的更标准方法是使用Queue.Queue. 但是,基于队列的解决方案的限制是只有一个线程可以读取消息。换句话说:读者消费信息。这种方法非常适合生产者-消费者范式。(您没有提到是否有多个线程在等待事件)。

对于多个阅读器线程,您还应该考虑pubsub(发布者/订阅者)解决方案,尽管我不知道 python 中有任何开箱即用的 pubsub 实现。

于 2013-10-02T20:54:23.640 回答