我正在研究并试图理解Python GIL以及在Python中使用多线程的最佳实践。我找到了这个演示文稿和这个视频。
我尝试复制演示文稿前4页中提到的奇怪和疯狂的问题。该问题也在视频中被讲师提到(前4分钟)。我编写了以下简单代码以复现该问题。
我尝试复制演示文稿前4页中提到的奇怪和疯狂的问题。该问题也在视频中被讲师提到(前4分钟)。我编写了以下简单代码以复现该问题。
from threading import Thread
from time import time
BIG_NUMBER = 100000
count = BIG_NUMBER
def countdown(n):
global count
for i in range(n):
count -= 1
start = time()
countdown(count)
end = time()
print('Without Threading: Final count = {final_n}, Execution Time = {exec_time}'.format(final_n=count, exec_time=end - start))
count = BIG_NUMBER
a = Thread(target=countdown, args=(BIG_NUMBER//2,))
b = Thread(target=countdown, args=(BIG_NUMBER//2,))
start = time()
a.start()
b.start()
a.join()
b.join()
end = time()
print('With Threading: Final count = {final_n}, Execution Time = {exec_time}'.format(final_n=count, exec_time=end - start))
但是实际结果与论文和视频完全不同!使用线程和不使用线程的执行时间几乎相同。有时候其中一个情况会比另一个略微快一些。
这是我在使用Windows 10下的多核处理器,使用CPython 3.7.3获得的结果。
Without Threading: Final count = 0, Execution Time = 0.02498459815979004
With Threading: Final count = 21, Execution Time = 0.023985862731933594
根据视频和文献,我所理解的是GIL防止两个线程在两个核心上同时进行真正的并行执行。那么如果这是真的,为什么最终计数变量(在多线程情况下)不像预期的那样为零,并且在每次执行结束时会是一个不同的数字,可能是因为同时操作线程导致的? 在比视频和文献中使用Python 3.2更新的Python版本中,是否有任何对GIL的更改导致了这些差异? 提前感谢。
count -= 1
不是原子操作,GIL不能防止系统在执行它时从一个线程切换到另一个线程。我认为GIL的主要影响是它从不允许线程真正并行运行。 - Solomon Slow