python之多線程

來源:互聯網
上載者:User

標籤:start   活動   聲明   ipc   自己   多工   isp   src   call   

聲明:樣本來源《python核心編程》

前言

  單線程處理多個外部輸入源的任務只能使用I/O多工,如:select,poll,epoll。

  特別值得注意的是:由於一個串列程式需要從每個 I/O 終端通道來檢查使用者的輸入,程式在讀取 I/O 終端通道時不能阻塞,因為使用者輸入的到達時間是不確定的,並且阻塞會妨礙其他 I/O 通道的處理。

  select,poll,epoll本質上都是同步I/O,因為他們都需要在讀寫事件就緒後自己負責進行讀寫,也就是說這個讀寫過程是阻塞的,而非同步I/O則無需自己負責進行讀寫,非同步I/O的實現只負責把資料從核心拷貝到使用者空間。

為此就引出了我們的主體多線程,多線程的特點:

  1. 本質上是非同步
  2. 需要多個並發活動
  3. 每個活動的處理順序可能是不確定的,或者說是隨機的、不可預測的。

什麼是進程?
進程就是一個執行中的程式。每個進程都擁有自己的地址空間、記憶體、資料棧以及其他用於跟蹤執行的輔助資料。作業系統管理其上所有進程的執行,並為這些進程合理地分配時間。進程也可以通過派生( fork 或 spawn)新的進程來執行其他任務,不過因為每個新進程也都擁有自己的記憶體和資料棧等,所以只能採用處理序間通訊( IPC)的方式共用資訊。

什麼是線程?
線程(有時候稱為輕量級進程)與進程類似,不過它們是在同一個進程下執行的,並共用相同的上下文。可以將它們認為是在一個主進程或“主線程”中並行啟動並執行一些“迷你進程”。

python中的多線程實現threading模組中的對象列表

ps:我們通過python實現多線程編程,主要用到的是threading.Thread對象

Thread對象常用屬性和方法

多線程樣本

context: python2.7.13

python通過Thread對象建立一個多線程執行個體,主要有3種方式:
  1. 建立 Thread 的執行個體,傳給它一個函數。
  2. 建立 Thread 的執行個體,傳給它一個可調用的類執行個體。
  3. 派生 Thread 的子類,並建立子類的執行個體。

ps:我們通常會選擇第一個或第三個方案。當你需要一個更加符合物件導向的介面時,會選擇後者。所以,建議使用第三種方案,它是最適合你的應用和未來擴充的方法

樣本1:建立 Thread 的執行個體,傳給它一個函數。
 1 #!/usr/bin/env python 2 #-*- coding:utf-8 -*- 3 import threading 4 from time import sleep,ctime 5  6 loops = [4,2] 7  8 def loop(nloop,nsec): 9     print "start loop",nloop,"at:",ctime()10     sleep(nsec)11     print "loop",nloop,‘done at:‘,ctime()12 13 def main():14     print "Starting at:",ctime()15     threads = []16     nloops = range(len(loops))17     #完成所有線程分配,並不立即開始執行18     for i in nloops:19         t = threading.Thread(target=loop,args=(i,loops[i]))20         threads.append(t)21     #開始調用start方法,同時開始所有線程22     for i in nloops:23         threads[i].start()24     #join方法:主線程等待所有子線程執行完成,再執行主線程接下來的操作。25     for i in nloops:26         threads[i].join()27 28     print "All done at:",ctime()29 if __name__=="__main__":30     main()
Starting at: Sun Jun 18 10:00:49 2017start loop 0 at: Sun Jun 18 10:00:49 2017start loop 1 at: Sun Jun 18 10:00:49 2017loop 1 done at: Sun Jun 18 10:00:51 2017loop 0 done at: Sun Jun 18 10:00:53 2017All done at: Sun Jun 18 10:00:53 2017Process finished with exit code 0
resault樣本2:建立 Thread 的執行個體,傳給它一個可調用的類執行個體
#!/usr/bin/env python#-*- encoding:utf-8 -*-import threadingfrom time import sleep,ctimeloops = [4,2]class ThreadFunc(object):    def __init__(self,func,args,name=""):        self.name = name        self.func = func        self.args = args    #使類具有函數行為,就像函數的代理(proxy)    def __call__(self):        self.func(*self.args)def loop(nloop,nsec):    print "start loop",nloop,"at:",ctime()    sleep(nsec)    print "loop",nloop,‘done at:‘,ctime()def main():    print "Starting at:",ctime()    threads = []    nloops = range(len(loops))    #完成所有線程分配,並不立即開始執行    for i in nloops:        t = threading.Thread(target=ThreadFunc(loop,(i,loops[i]),loop.__name__))        threads.append(t)    #開始調用start方法,同時開始所有線程    for i in nloops:        threads[i].start()    #join方法等待子線程執行完成,再執行主線程接下來的操作。    for i in nloops:        threads[i].join()    print "All done at:",ctime()if __name__=="__main__":    main()
傳入類執行個體
Starting at: Sun Jun 18 10:03:52 2017start loop 0 at: Sun Jun 18 10:03:52 2017start loop 1 at: Sun Jun 18 10:03:52 2017loop 1 done at: Sun Jun 18 10:03:54 2017loop 0 done at: Sun Jun 18 10:03:56 2017All done at: Sun Jun 18 10:03:56 2017Process finished with exit code 0
resault樣本3:派生 Thread 的子類,並建立子類的執行個體。自訂類MyThread
  1. 檔案名稱:mythread.py,
  2. 內容:MyThread為threading.Thread的衍生類別
#!/usr/bin/env python#-*- coding:utf-8 -*-import threadingfrom time import sleep,ctimeclass MyThread(threading.Thread):    def __init__(self,func,args,name=""):        threading.Thread.__init__(self)        self.name = name        self.func = func        self.args = args    def get_res(self):        return self.res    def run(self):        print "Starting",self.name,"at:",ctime()        self.res = self.func(*self.args)        print self.name,"finish at:",ctime()
菲波那切數列,階乘,累加單線程也多線程對比
#!/usr/bin/env python#-*- coding:utf-8 -*-#MyThread為自訂的threading.Thread的衍生類別from mythread import MyThreadfrom time import sleep,ctime#斐波那契數列def fib(x):    sleep(0.005)    if x < 2:return 1    return (fib(x-2)+fib(x-1))#階乘def fac(x):    sleep(0.1)    if x < 2:return 1    return (x*fac(x-1))#累加def sum(x):    sleep(0.1)    if x < 2:return 1    return (x + sum(x-1))funcs = [fib,fac,sum]n = 12def main():    nfuncs = range(len(funcs))    print "---SINGLE THREAD---"    for i in nfuncs:        print "Starting",funcs[i].__name__,"at:",ctime()        print funcs[i](n)        print funcs[i].__name__,"finish at:",ctime()    print "\n---MULTIPLE THREADS---"    threads = []    for i in nfuncs:        t = MyThread(funcs[i],(n,),funcs[i].__name__)        threads.append(t)    for i in nfuncs:        threads[i].start()    for i in nfuncs:        threads[i].join()        print threads[i].get_res()    print "All Done!"if __name__ == ‘__main__‘:    main()
---SINGLE THREAD---Starting fib at: Sun Jun 18 09:12:17 2017233fib finish at: Sun Jun 18 09:12:24 2017Starting fac at: Sun Jun 18 09:12:24 2017479001600fac finish at: Sun Jun 18 09:12:26 2017Starting sum at: Sun Jun 18 09:12:26 201778sum finish at: Sun Jun 18 09:12:27 2017---MULTIPLE THREADS---Starting fib at: Sun Jun 18 09:12:27 2017Starting fac at: Sun Jun 18 09:12:27 2017Starting sum at: Sun Jun 18 09:12:27 2017fac finish at: Sun Jun 18 09:12:28 2017sum finish at: Sun Jun 18 09:12:28 2017fib finish at: Sun Jun 18 09:12:34 201723347900160078All Done!Process finished with exit code 0
resault

  以單線程模式運行時,只是簡單地依次調用每個函數,並在函數執行結束後立即顯示相應的結果。

  而以多線程模式運行時,並不會立即顯示結果。 因為我們希望讓 MyThread 類越通用越好(有輸出和沒有輸出的調用都能夠執行),我們要一直等到所有線程都執行結束,然後調用get_res()方法來最終顯示每個函數的傳回值。

 

python之多線程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.