我想用同步stop()
方法实现一个线程。
我见过这样的版本:
class Thread1:
def __init__(self):
self._stop_event = threading.Event()
self._thread = None
def start(self):
self._thread = threading.Thread(target=self._run)
self._thread.start()
def stop(self):
self._stop_event.set()
self._thread.join()
def _run(self):
while not self._stop_event.is_set():
self._work()
def _work(self):
print("working")
但是我已经读过原子操作是线程安全的,在我看来它可以在没有Event
的情况下完成。所以我想出了这个:
class Thread2:
def __init__(self):
self._working = False
self._thread = None
def start(self):
self._working = True
self._thread = threading.Thread(target=self._run)
self._thread.start()
def stop(self):
self._working = False
self._thread.join()
def _run(self):
while self._working:
self._work()
def _work(self):
print("working")
它认为类似的实现在C中被认为是不正确的,因为编译器可以将_working
放到寄存器中(甚至优化掉),并且工作线程永远不会知道变量已经改变。可以在Python中发生类似的事情吗?这个实现是否正确?我的目标不是完全避免事件或锁定,只是想了解这种原子操作的事情。
答案 0 :(得分:1)
据我所知,它在Python中也是不正确的,因为_working
仍然可以放入注册或以其他方式进行优化,或者可能会发生一些会改变它的价值的其他事情。读取和写入此字段可由处理器任意重新排序。
嗯,让我们说在多线程世界中你真的要问:为什么这不应该工作,而是为什么要保证工作 。
在大多数情况下说多线程在CPython中更容易一些,因为GIL可以保证:
请记住,GIL是一个实现细节,如果没有它重写CPython,它可能会消失。
另请注意,应该在任何实际系统中以这种方式实现它。