假设一个实现字段WorkerThread
的类running
,它指示线程在启动后是否应该继续工作。
class WorkerThread(threading.Thread):
running = False
def run(self):
self.running = True
while self.running:
# .. do some important stuff
pass
def main():
t = WorkerThread()
t.start()
# .. do other important stuff
t.running = False
t.join()
从主线程修改t.running
时是否存在可能出错的问题,而不将读取和写入操作锁定到此字段?它是什么?
答案 0 :(得分:1)
主线程和工作线程可以在不共享缓存的核心上运行。由于缺少同步,对t.running
的写入可能从不从主线程的缓存共享到工作线程的缓存。
什么同步意味着不仅仅是“我想要独占访问”。它还意味着,“我想分享我对其他线程的写入,并查看来自其他线程的写入”。没有同步意味着你不需要那些东西。不同步并不会阻止它们发生(在某些系统/架构上,它们的发生频率会高于其他系统/架构),它无法保证它们会发生。
在实践中,您可能会发现,如果CPython定期使用GIL,这些事情即使在与英特尔不同的架构上也没有连贯的缓存。
答案 1 :(得分:1)
根据您的要求使用threading.Event()
对象而不是标记。
class WorkerThread(threading.Thread):
def __init__(self):
super(WorkerThread, self).__init__()
self.running = threading.Event()
def run(self):
self.running.set()
while self.running.is_set():
# .. do some important stuff
pass
def halt(self):
self.running.clear()
def main():
t = WorkerThread()
t.start()
# .. do other important stuff
t.halt()
t.join()
并检查是否正在运行t.is_alive()
。
答案 2 :(得分:0)
“running”字段是共享状态,你需要用某种监视器来保护它。如果没有对此共享状态的同步访问,则其可见性语义很难推理,并且您将获得意外结果。