三、程序和執行緒、協程在python中的使用
阿新 • • 發佈:2018-11-16
三、程序和執行緒、協程在python中的使用
1、多程序一般使用multiprocessing庫,來利用多核CPU,主要是用在CPU密集型的程式上,當然生產者消費者這種也可以使用。多程序的優勢就是一個子程序崩潰並不會影響其他子程序和主程序的執行,但缺點就是不能一次性啟動太多程序,會嚴重影響系統的資源排程,特別是CPU使用率和負載。使用多程序可以檢視文章《python 多程序使用總結》。注:python2的程序池在類中的使用會有問題,需要把類函式定義成全域性函式。具體可參考 http://bbs.chinaunix.net/thread-4111379-1-1.html
2、多執行緒一般是使用threading庫,完成一些IO密集型併發操作。多執行緒的優勢是切換快,資源消耗低,但一個執行緒掛掉則會影響到所有執行緒,所以不夠穩定。現實中使用執行緒池的場景會比較多,具體可參考《 python執行緒池實現》。
3、協程一般是使用gevent庫,當然這個庫用起來比較麻煩,所以使用的並不是很多。相反,協程在tornado的運用就多得多了,使用協程讓tornado做到單執行緒非同步,據說還能解決C10K的問題。所以協程使用的地方最多的是在web應用上。
總結一下就是IO密集型一般使用多執行緒或者多程序,CPU密集型一般使用多程序,強調非阻塞非同步併發的一般都是使用協程,當然有時候也是需要多程序執行緒池結合的,或者是其他組合方式。
下面我們使用程序加協程來做加法和乘法的計算任務同時計算,也就是併發計算:
# coding:utf-8 import gevent import multiprocessing,os import time def f1(s): a = s while a<33: a = a + 1 print('計算相加 程序ID:%s'%os.getpid(),a) # gevent.sleep(1) def f2(s): d=1 for i in range(s,30): d = d*i print('計算相乘 程序ID:%s'%os.getpid(),d) # gevent.sleep(1) def gv1(i): g1 = gevent.spawn(f1, i) g1.join() def gv2 (i): g2 = gevent.spawn(f2, i) g2.join() if __name__=='__main__': start = time.clock() # # 程序池 # pool = multiprocessing.Pool(2) # pool.apply_async(gv1,(1,)) # pool.apply_async(gv2,(1,)) # pool.close() # pool.join() # 單開程序 pool = [] p1 = multiprocessing.Process(target=f1,args=(1,)) p2 = multiprocessing.Process(target=f2,args=(1,)) pool.append(p1) pool.append(p2) p1.start() p2.start() for item in pool: item.join() print(time.clock()-start)
自動化學習。