参考:
Python GIL 系列之通过实例认识Python的GIL
Python GIL 系列之再谈Python的GIL
本文通过对比测试来证明下单线程、多线程、多进程的‘并发‘计算能力
from threading import Thread
from timeit import Timer
from multiprocessing import Process
G_COUNT = 100000000
G_THREAD_COUNT = 2
G_PROCESS_COUNT = 2
def countdown(n):
while n > 0:
n -= 1
def thread_start(thread_pool):
for thread in thread_pool:
thread.start()
def thread_join(thread_pool):
for thread in thread_pool:
thread.join()
def process_start(process_pool):
thread_start(process_pool)
def process_join(process_pool):
thread_join(process_pool)
def single_thread():
count = G_COUNT
thread_pool = []
thread = Thread(target=countdown, args=(count,))
thread_pool.append(thread)
thread_start(thread_pool)
thread_join(thread_pool)
def multi_thread():
count = G_COUNT
thread_pool = []
for i in range(G_THREAD_COUNT):
thread = Thread(target=countdown, args=(count//G_THREAD_COUNT,))
thread_pool.append(thread)
thread_start(thread_pool)
thread_join(thread_pool)
def multi_process():
count = G_COUNT
process_pool = []
for i in range(G_PROCESS_COUNT):
process = Process(target=countdown, args=(count//G_PROCESS_COUNT,))
process_pool.append(process)
process_start(process_pool)
process_join(process_pool)
def main():
t = Timer(single_thread)
print("Single thread:%f" % (t.timeit(1),))
t = Timer(multi_thread)
print("Multi thread:%f" % (t.timeit(1),))
t = Timer(multi_process)
print("Multi process:%f" % (t.timeit(1),))
if __name__ == "__main__":
main()
说明:
上述程序在多核的mac pro上运行结果如下
Single thread:4.297631
Multi thread:5.357289
Multi process:2.101515
说明:上述程序运行多次,测试得到的结果不完全一样,但是基本趋势以及多少对比差不多。
为什么会这样呢?与我们所想象的不一样:多线程应该是并发的,应该耗时比较低才对。
在CPython解释器中有把锁:GIL。因为有所,所以在线程并不能真正的并发,而是串行的,而且在线程切换时时需要费时,所以才会出现这样的结果。
关于GIL的相关内容,请参考这个系列的另外一篇文章eventlet引发的学习:python GIL