为什么GIL不允许性能不佳的线程代码?

2024-09-30 08:36:20 发布

您现在位置:Python中文网/ 问答频道 /正文

顺序代码(seq.py)所用的时间

import time

def countDown(n):
    while n > 0:
        n -= 1

n = 50000000
start = time.time()
countDown(n)
end = time.time()
print(end-start)

是的

$ python3.6 seq.py 
 4.209718227386475
$ python3.6 seq.py 
 4.007786750793457
$ python3.6 seq.py 
 4.0265843868255615
$

线程版本(usingThreads.py)所用的时间

from threading import Thread
import time
def countDown(n):
    while n > 0:
        n -= 1


n = 50000000

t1 = Thread(target=countDown, args=(n//2,))
t1.daemon = True
t2 = Thread(target=countDown, args=(n//2,))
t2.daemon = True

start = time.time()
t1.start()
t2.start()
t1.join()
t2.join()
end = time.time()
print(end-start)

是的

$ python3.6 usingThreads.py 
 4.1083903312683105
$ python3.6 usingThreads.py 
 4.093154668807983
$ python3.6 usingThreads.py 
 4.092989921569824
$ python3.6 usingThreads.py 
 4.116031885147095
$

$ nproc
 4
$

Python解释器不应该允许CPU绑定的线程释放GIL。你知道吗

期望usingThreads.pyseq.py花费更多的执行时间,因为

1)一次执行任何一个线程,尽管有4个内核

2)由thread2(反之亦然)从thread1获取GIL的失败尝试所花费的时间应该会增加执行的延迟。你知道吗

编辑:

n=500000000

$ python3.6 seq.py 
 40.22602105140686
$ python3.6 seq.py 
 40.510098457336426
$ python3.6 seq.py 
 40.04688620567322
$
$ python3.6 usingThreads.py 
 40.91394829750061
$ python3.6 usingThreads.py 
 42.30081081390381
$ python3.6 usingThreads.py 
 41.328694581985474

问题:

为什么usingThread.py的性能比seq.py好?你知道吗


Tags: pyimporttimedef时间线程threadstart
1条回答
网友
1楼 · 发布于 2024-09-30 08:36:20

两个版本的代码所做的工作量相同,所以所花的时间几乎相同(都计算了50000000次)。你知道吗

gil使得它们不会并行运行(因此线程版本不会更快),但是上下文切换的开销相对较小,因此您得到了几乎相同的结果。你知道吗

这里有一个解释http://www.dabeaz.com/python/UnderstandingGIL.pdf

他和你用的是同一个例子,在这个演示中,当他使用一个以上CPU的计算机时,他得到了一个较慢的线程版本,他很好地解释了这一点,当你使用一个以上的CPU时,你会得到更多的开销(更多的上下文切换尝试),这会使你的程序变慢

相关问题 更多 >

    热门问题