停止线程:标志与事件
问题描述
我看到了e.g. here使用Event
停止线程的示例,我认为布尔标志可以完成此工作。
活动
class MyThread(threading.Thread):
def __init__(self):
self._please_stop = threading.Event()
def run(self):
while not self._please_stop.is_set():
[...]
def stop(self):
self._please_stop.set()
旗帜
class MyThread(threading.Thread):
def __init__(self):
self._please_stop = False
def run(self):
while not self._please_stop:
[...]
def stop(self):
self._please_stop = True
在这里使用Event
有什么好处?未使用其wait
方法。有什么比布尔标志更好的?
如果相同的Event
在多个线程之间共享,我可以理解这一点,但在其他情况下,我无法理解。
This mailing list thread建议Event
会更安全,但我不清楚原因。
更准确地说,我不理解这两段话:
如果我对GIL的理解正确,它会将所有访问同步到 Python数据结构(例如我的布尔值‘Terminated’标志)。如果是这样的话 既然如此,何必为此费心使用线程化。事件? GIL是一个实现细节,并依赖于它进行同步 对你来说,事情并不是未来的证据。你可能会有很多 警告,但是使用threading.Event()并不难,而且更难 从长远来看,这是正确和安全的。
我同意使用Event
几乎不会增加任何开销,因此我可以坚持这一点,但我想了解FLAG方法的局限性。
(我使用的是Python3,所以我并不担心Python2的限制(如果有),尽管这些限制在这里完全值得一提。)
解决方案
我认为您引用的线程中的含义是设置布尔值不一定是atomic在Python中的操作。虽然在所有Python对象(GIL)上设置全局锁会使所有设置属性的操作暂时看起来原子,但这样的锁将来可能不会存在。使用Event
使操作成为原子操作,因为它使用自己的锁进行访问。
原子的链接指向一个Java问题,但它的相关性并不因此而降低。
相关文章