Python 通过所有函数加入线程的竞争条件

Python race condition with joining threads via all function

请查看下面的代码片段,它无法通过 Python 3.10 本地的第一个 运行。

当我尝试 join 内置 all 函数中的所有线程时,总是有一个线程仍然存在。

这里的问题是什么,为什么会出现竞争条件?

import time
from threading import Thread

def expose_race_condition(run_index: int) -> None:
    threads: list[Thread] = [
        Thread(target=time.sleep, args=(1,)) for _ in range(10)
    ]
    for thread in threads:
        thread.start()

    # RACE CONDITION IS HERE
    assert not all(thread.join() for thread in threads)
    for thread_index, thread in enumerate(threads):
        # Uncommenting the below line defeats the race condition
        # assert not thread.join()
        assert (
            not thread.is_alive()
        ), f"Worker {thread_index} in run {run_index} was still alive."
    print(f"Completed run {run_index}")

if __name__ == "__main__":
    for i in range(10_000):
        expose_race_condition(i)

抱歉,我不明白你想做什么。这一行,例如:

   assert not all(thread.join() for thread in threads)

只是没有意义。 .join()总是returnsNone,所以和

一样
   assert not all(None for thread in threads)

除了它有连接线程的副作用。 all() short-circuits 第一次看到 False 值,None 是,所以实际上只调用了第一个 .join()all(...) returns False,所以 not all(...) returns True,所以 assert 成功了。就像:

    threads[0].join()
    assert True

短期课程:任何 任何注意值 thread.join() returns 的代码可能 flat-out 已损坏,因为 None 是它会看到的唯一值。