Python中的线程与普通

时间:2018-11-25 20:02:57

标签: python multithreading time gil

import time
import threading
import multiprocessing

def fn():
    '''since all 3 functions were identical you can just use one ...'''
    x = 0
    while  x < 100000000:
        x += 1




def TEST_THREADS():
    new_thread1  = threading.Thread(target = fn , args = ())
    new_thread2  = threading.Thread(target = fn, args = ())
    new_thread1.start()
    new_thread2.start()
    new_thread1.join()
    new_thread2.join()

def TEST_NORMAL():
    fn()
    fn()

def TEST_MULTIPROCESSING():
    new_thread1  = multiprocessing.Process(target = fn , args = ())
    new_thread2  = multiprocessing.Process(target = fn, args = ())
    new_thread1.start()
    new_thread2.start()
    new_thread1.join()
    new_thread2.join()
if __name__ == "__main__":  
    '''It is very important to use name == __main__ guard code with threads         and multiprocessing'''
    import timeit
    print ("Time to Run 1x: %0.2fs"%(timeit.timeit(fn,number=1),))
    print ("NORMAL:%0.2fs"%(timeit.timeit(TEST_NORMAL,number=1),))
    print ("Threaded: %0.2fs"%(timeit.timeit(TEST_THREADS,number=1),))
    print ("Multiprocessing: %0.2fs"%    (timeit.timeit(TEST_MULTIPROCESSING,number=1),))

我发现了有关GIL和线程的有趣演示: http://www.dabeaz.com/python/NewGIL.pdf 所以我写了类似的代码,但是得到了奇怪的结果:

Time to Run 1x: 11.60s
NORMAL:23.15s
Threaded: 23.43s
Multiprocessing: 1.19s

如您所见,线程方法的运行速度比普通方法快一倍或相等(0.28秒不是太多)。 我发现了一些文章和类似的问题,但是到处都是演示文稿,结果却很慢。

我做错了什么还是新的Python版本改进了GIL?

但是,多处理也变得疯狂,并且工作速度比其他方法快20倍!可以吗

1 个答案:

答案 0 :(得分:1)

在现代Python中,GIL并没有以前那么糟糕(以前,您可能希望CPU绑定的线程代码运行得明显慢一些),因此您的观察结果大致上就是您期望的。

从个人经验来看,CPython 2.7上的许多CPU绑定线程可以使用接近两个CPU内核,并且完成的工作量不到内核工作量的75%。自从他们rewrote the GIL in CPython 3.2以来,那笔开销基本上消失了;您仍然没有从线程中获得任何收益,但是最终使用了1-1.1内核的计算能力,并完成了95-100%的内核工作。基本上,GIL不再有意义地降低代码速度,但是它仍然可以防止您受益于使用不基于第三方GIL释放扩展程序(例如numpy)的CPU绑定代码进行线程化。