在这里没有锁定写入操作时可能出现什么问题?

时间:2013-11-25 07:53:14

标签: python multithreading thread-safety locking

假设一个实现字段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时是否存在可能出错的问题,而不将读取和写入操作锁定到此字段?它是什么?

3 个答案:

答案 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”字段是共享状态,你需要用某种监视器来保护它。如果没有对此共享状态的同步访问,则其可见性语义很难推理,并且您将获得意外结果。