python 多線程編程並不能真正利用多核的CPU


昨天晚上在寢室寫python多線程的時候,用了幾個測試的程序,分別是遞歸方法求斐波那契數的值。分別采用單線程一個一個執行的方法和采用多線程調用的方法。觀察所用的時間基本上差不多的。

 

然后我在每個函數內部加入sleep()函數以后,分別讓它們睡零點幾秒鍾。這樣一來,明顯多線程執行所用的時間要少很多。

這時我突然好奇,想看看在用python多線程執行的時候,是否可以利用CPU多個核心呢?我的筆記本是i3處理器,雙核,4線程(我至今不知道這里所指的4線程具體是什么意思,之前和老師交流過,猜測可能是在硬件上做了像我們軟件執行的時候的躲進程這樣類似的東西,但是不確定),反正在我的系統下的系統監視器里面可以看到有4個核的利用率頻線。我就觀察這種曲線的變化方式:當我每一個都是單線程地運行的時候。顯示的畫面中有一個CPU爆滿;但是在多線程運行的時候,是每一個利用一些。

下面是系統監視器顯示情況:

這是運行時間對比:

 

顯然多線程運行的時候時間反而長了很多,雖然有上下文切換的時間損耗,但是若是能夠利用多核的話也不至於那么慢,另外由系統監視器可以看出多線程的時候也沒有把各個核利用率達到很高的一個水平。所以當時推斷python的多線程並沒有很多的利用多核CPU,其實之前也有聽說過python對於多核CPU支持是個缺陷,現在是有真的體會,但是我只是憑自己的小實驗,也不能有很打保證啊,也只是猜測,后來翻了一下《python參考手冊》發現有這么一句話,看來是真的證實了我自己的猜想啊!!!

盡管是很低級的問題,但是對於初學的我來說,還是有很大的喜悅的。

下面是實驗的代碼:

fab.py:

 1 # -*- coding: utf-8 -*-
2 from myThread import MyThread
3 from time import ctime
4 from time import sleep
5 import sys
6
7 def fib(x):
8 # sleep(0.005)
9 if x<2:return 1
10 return (fib(x-2) + fib(x-1))
11
12 def fac(x):
13 # sleep(0.05)
14 if x<2:return 1
15 return (fac(x-2)+fac(x-1))
16
17 def sum(x):
18 # sleep(0.05)
19 if x<2:return 1
20 return (sum(x-2)+sum(x-1))
21
22 funcs = [fib,fac,sum]
23 n = 35
24
25 def main():
26 nfuncs = range(len(funcs))
27 sys.stdout.write('***SINGLE THREAD\n')
28 for i in nfuncs:
29 sys.stdout.write('starting %s at: %s\n' %(funcs[i].__name__,ctime()))
30 print funcs[i](n)
31 sys.stdout.write("%s finished at: %s\n"% (funcs[i].__name__,ctime()))
32 sys.stdout.write('\n***MULTIPLE THREADS\n')
33
34 threads = []
35
36 for i in nfuncs:
37 t = MyThread(funcs[i],(n,),funcs[i].__name__)
38 threads.append(t)
39
40 for i in nfuncs:
41 threads[i].start()
42
43 for i in nfuncs:
44 threads[i].join()
45 print threads[i].getResult()
46
47 sys.stdout.write('all done\n')
48
49 if __name__ == '__main__':
50 main()

myThread.py:

 1 import threading 
2 from time import ctime
3 import sys
4
5 class MyThread(threading.Thread):
6 def __init__(self,func,args,name=''):
7 threading.Thread.__init__(self)
8 self.name = name
9 self.func = func
10 self.args = args
11
12 def getResult(self):
13 return self.res
14
15 def run(self):
16 sys.stdout.write("starting %s at: %s\n" % (self.name,ctime()))
17 self.res = apply(self.func,self.args)
18 sys.stdout.write("%s finished at: %s\n" % (self.name,ctime()))





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM