多線程和單線程的執行效率問題

一提到多線程通常你們的第一感受就是能夠提高程序性能,在實際的操做中每每遇到性能的問題,都嘗試使用多線程來解決問題,但多線程程序並非在任何狀況下都能提高效率,在一些狀況下偏偏相反,反而會下降程序的性能。這裏給出兩個簡單的例子來講明下:性能優化

程序1:多線程

 1 import threading
 2 from time import ctime
 3 
 4 class MyThread(threading.Thread):
 5     def __init__(self, func, args, name):
 6         threading.Thread.__init__(self)
 7         self.name = name
 8         self.func = func
 9         self.args = args
10 
11     def run(self):
12         print 'starting', self.name, 'at:',ctime()
13         apply(self.func, self.args)
14         print self.name, 'finished at:', ctime()
15 
16 def fun1(x):
17     y = 0
18     for i in range(x):
19         y+=1
20 
21 def fun2(x):
22     y = 0
23     for i in range(x):
24         y+=1
25         
26 def main():
27     print 'staring single thread at:',ctime()
28     fun1(10000000)
29     fun2(10000000)
30     print 'finished single thread at:',ctime()
31 
32     t1 = MyThread(fun1,(10000000,),fun1.__name__)
33     t2 = MyThread(fun2,(10000000,),fun2.__name__)
34     t1.start()
35     t2.start()
36     t1.join()
37     t2.join()
38     
39     print 'all done'
40     
41 if __name__ == '__main__':
42     main()

 該程序執行結果爲:併發

staring single thread at: Sat Dec 08 10:27:11 2012
finished single thread at: Sat Dec 08 10:27:14 2012
starting  fun1  at:  Sat Dec 08 10:27:14 2012
starting  fun2  at:  Sat Dec 08 10:27:14 2012
fun1  finished at:Sat Dec 08 10:27:21 2012
fun2  finished at:Sat Dec 08 10:27:21 2012
all doneapp

結果顯示對於一樣的問題多線程耗費了多一倍的時間,fun1,、fun2都是計算型程序,這就意味着兩個代碼都須要佔用CPU資源,雖然採用了多線 程但CPU資源是惟一的(不考慮多CPU多核的狀況),同一時刻只能一個線程使用,致使多線程沒法真正的併發,相反因爲線程的切換的開銷,效率反而有明顯 的降低。由此看以在單CPU的場景下對於計算密集型的程序,多線程並不能帶來效率的提高。ide

程序2:性能

 1 import threading
 2 from time import ctime
 3 
 4 class MyThread(threading.Thread):
 5     def __init__(self, func, args, name):
 6         threading.Thread.__init__(self)
 7         self.name = name
 8         self.func = func
 9         self.args = args
10 
11     def run(self):
12         print 'starting', self.name, 'at:',ctime()
13         apply(self.func, self.args)
14         print self.name, 'finished at:', ctime()
15 
16 def fun1(x):
17     for i in range(x):
18         fd = open('1','w')
19         fd.close()
20 
21 def fun2(x):
22     y = 0
23     for i in range(x):
24         y+=1
25         
26 def main():
27     print 'staring single thread at:',ctime()
28     fun1(15000)
29     fun2(50000000)
30     print 'finished single thread at:',ctime()
31 
32     t1 = MyThread(fun1,(15000,),fun1.__name__)
33     t2 = MyThread(fun2,(50000000,),fun2.__name__)
34     t1.start()
35     t2.start()
36     t1.join()
37     t2.join()
38     
39     print 'all done'
40     
41 if __name__ == '__main__':
42     main()
View Code

該程序執行結果爲:優化

staring single thread at: Sat Dec 08 11:03:30 2012
finished single thread at: Sat Dec 08 11:03:46 2012
starting  fun1  at:  Sat Dec 08 11:03:46 2012
starting  fun2  at:  Sat Dec 08 11:03:46 2012
fun2 finished at: Sat Dec 08 11:03:55 2012
fun1 finished at: Sat Dec 08 11:03:58 2012
all donespa

結果顯示這個程序採用多線程比單線程的效率有明顯的提高。這是因爲fun1主要是文件的操做,fun2是計算操做,單線程的狀況下,雖然兩個程序主 要使用不一樣的資源可是在線程內部只能串行執行,在IO操做的時候,CPU實際是無事可作。多線程的狀況下,若是一個線程在等待IO操做,線程會立刻調度到 另一個線程上,併發的使用了不一樣的資源。操作系統

結論:線程

線程自己因爲建立和切換的開銷,採用多線程不會提升程序的執行速度,反而會下降速度,可是對於頻繁IO操做的程序,多線程能夠有效的併發。

對於包含不一樣任務的程序,能夠考慮每一個任務使用一個線程。這樣的程序在設計上相對於單線程作全部事的程序來講,更爲清晰明瞭,好比生產、消費者問題。

在實際的開發中對於性能優化的問題須要考慮到具體的場景來考慮是否使用多線程技術。

 

 

操做系統 併發程序執行的特色:
併發環境下,因爲程序的封閉性被打破,出現了新的特色:
①程序與計算再也不一一對應,一個程序副本能夠有多個計算
併發程序之間有相互制約關係,直接制約體現爲一個程序須要另外一個程序的計算結果,間接制約體現爲多個程序競爭某一資源,如處理機、 緩衝區等。
併發程序在執行中是走走停停,斷續推動的。

與並行區別 編輯

併發當有多個線程在操做時,若是系統只有一個CPU,則它根本不可能真正同時進行一個以上的線程,它 只能把CPU運行時間劃分紅若干個時間段,再將時間 段分配給各個線程執行,在一個時間段的線程代碼運行時,其它線程處於掛起狀。.這種方式咱們稱之爲併發(Concurrent)。
並行:當系統有一個以上CPU時,則線程的操做有可能非併發。當一個CPU執行一個線程時,另外一個CPU能夠執行另外一個線程,兩個線程互不搶佔CPU資源,能夠同時進行,這種方式咱們稱之爲並行(Parallel)。
區別:併發和並行是即類似又有區別的兩個概念,並行是指兩個或者多個事件在同一時刻發生;而併發是指兩個或多個事件在同一時間間隔內發生。在 多道程序環境下, 併發性是指在一段時間內宏觀上有多個程序在同時運行,但在 單處理機系統中,每一時刻卻僅能有一道程序執行,故微觀上這些程序只能是分時地交替執行。假若在 計算機系統中有多個 處理機,則這些能夠併發執行的程序即可被分配到多個處理機上,實現 並行執行,即利用每一個處理機來處理一個可併發執行的程序,這樣,多個程序即可以同時執行。 [2]  
相關文章
相關標籤/搜索