Stop a thread: flag vs. Event
我看到了一些例子,例如这里使用
1 2 3 4 5 6 7 8 9 10 11 | 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() |
旗帜
1 2 3 4 5 6 7 8 9 10 11 | 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 |
这里使用
如果同一个
这个邮件列表提示
更准确地说,我不理解这两段:
If I understand the GIL correctly, it synchronizes all access to
Python data structures (such as my boolean 'terminated' flag). If that
is the case, why bother using threading.Event for this purpose?The GIL is an implementation detail and relying on it to synchronize
things for you isn't futureproof. You're likely to have lots of
warning, but using threading.Event() isn't any harder, and it's more
correct and safer in the long term.
我同意使用
(我使用的是python3,所以我不关心python2的限制,如果有的话,尽管在这里完全值得一提。)
编程通常不仅仅是让代码在今天工作,而是让它在将来所做的更改中继续工作。
- 其他的Python实现没有gil。我明天要在Pypy上运行它吗?
- 实际上,我需要将工作分散到几个流程中。在
multiprocessing 中交换…它实现了Event() ,但如果只使用局部变量,则会失败。 - 结果是只有在其他几个线程认为应该停止时,代码才应该停止。好吧,用
Semaphore() 代替Event() …但是很容易用变量错误地实现。
所以,根据字节码如何被中断以及何时可以释放gil,您很可能可以在python中完美地编写多线程程序。但是如果我稍后阅读和更改您的代码,那么如果您使用标准的同步原语,我会更高兴。
我认为您引用的线程中的含义是,设置布尔值不一定是Python中的原子操作。虽然在所有Python对象(gil)上都有一个全局锁,但目前设置属性的所有操作都是原子操作,但这种锁在将来可能不存在。使用
原子的链接是一个Java问题,但与此无关。