计算密集的线程在Python 3中“悬挂” - 为什么会这样?

时间:2016-07-30 13:24:26

标签: python multithreading blocking

我对Python比较陌生,但在编码方面有点熟练。这段小代码让我发疯。为什么地球上的方法 summe()如此顽固?线程似乎按顺序处理。这意味着,只有前一个Thread已经结束,才会启动每个下一个Thread。我不知道为什么?所有四个线程应该“并行”启动并“并行”工作。由于GIL的限制,即使它们仅在单个Core上运行。

使用方法 count()的相同步骤按预期工作“并行”。

亲爱的互联网,请帮助我!...

保罗:)

#!/usr/bin/python3

import threading

# Hanging...
def summe(n):
    print("Start")
    s = sum(range(n))
    print("Done")

# Works like a charm
def count(n):
    print("Start")
    while n > 0:
        n = n-1
    print("Done")

# This works
for i in range(3):
    threading.Thread(target=count,args=(10000000000000,)).start()

# This hangs...
for i in range(3):
    threading.Thread(target=summe,args=(10000000000000,)).start()

1 个答案:

答案 0 :(得分:1)

由于GIL,像sum这样的内置函数是原子的;一旦它启动,它将不会被中断,直到它完成。虽然可能,但是在切换上下文以允许下一个线程启动之前,线程系统可以选择仅执行summe的第一行,这是非常不可能的。你看到的“挂起”是第一个线程中的sum阻塞,直到它最终完成。

另一方面,在count中,没有一个长的原子操作阻塞GIL;只是很多(和很多很多......)小操作,它允许很多机会启动每个线程并返回主线程。使用n的小得多的值,您可以看到每个count线程开始,然后片刻之后它们就会完成。同样,您可以观察到几乎连续运行的三个summe线程(在我运行的一个测试中,第一个运行完成,然后开始另外两个并行运行)。