在很早的时候,就听网上的文章说:
python有GIL,所以在单进程内,即使使用多线程也无法利用到多核的优势,同一时刻,python的字节码只会运行在一个cpu上。
以前也是奉为真理,直到今天在对自己的python server做性能测试的时候,发现一个python进程的cpu居然达到了120%。
当用c++编程的时候,如果使用多线程,那么确实进程cpu超过100%非常正常,但是对python来说,似乎这样就和网上的文章冲突了。
所以还是决定自己亲身试验一下,编写代码如下:
1 2 3 4 5 6 7 8 9 10 11 |
from thread import start_new_thread def worker(): while 1: #print 1 pass for it in range(0, 15): start_new_thread(worker, ()) raw_input() |
运行环境为: centos6.4 64位, python 2.7.
得到的结果如下:
可以清楚的看到,pid为31199的python进程cpu达到了787.9%,接近理论能达到的最大值 800%。
而上方的8个cpu也分别达到了近100%的利用率。
如果只是按照以上测试结果,确实可以得出的结论:python使用单进程,多线程确实能够使用到多核cpu,并不是网上传的结论。
但是,还是希望如果有读者对这块有更深入的研究能够进行批评指正,谢谢~
8月15日补充
感谢 la.onger 等几位博友的讨论,现在增加一个测试,用来测试纯cpu计算用一个线程or多个线程完成的总时间的差别,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
import time from threading import Thread LOOPS = 1000000 THREAD_NUM = 10 STEP_SIZE = 94753434 class Test(object): num = 1 def work(self): for it in xrange(0, LOOPS): if self.num > STEP_SIZE: self.num -= STEP_SIZE else: self.num += STEP_SIZE def one_thread_test(self): self.num = 1 begin_time = time.time() for v in xrange(0, THREAD_NUM): self.work() print 'time passed: ', time.time() - begin_time def multi_thread_test(self): self.num = 1 t_list = [] begin_time = time.time() for v in xrange(0, THREAD_NUM): t = Thread(target=self.work) t.start() t_list.append(t) for it in t_list: it.join() print 'time passed: ', time.time() - begin_time t = Test() t.one_thread_test() t.multi_thread_test() |
输入结果如下:
1 2 |
time passed: 3.44264101982 time passed: 7.22910785675 |
使用多线程后,比不用多线程还慢
为了与c++版做对比,也开发了c++代码如下: