本文實例總結了Python多進程并發與多線程并發。分享給大家供大家參考,具體如下:
這里對python支持的幾種并發方式進行簡單的總結。
Python支持的并發分為多線程并發與多進程并發(異步IO本文不涉及)。概念上來說,多進程并發即運行多個獨立的程序,優勢在于并發處理的任務都由操作系統管理,不足之處在于程序與各進程之間的通信和數據共享不方便;多線程并發則由程序員管理并發處理的任務,這種并發方式可以方便地在線程間共享數據(前提是不能互斥)。Python對多線程和多進程的支持都比一般編程語言更高級,最小化了需要我們完成的工作。
一.多進程并發
Mark Summerfield指出,對于計算密集型程序,多進程并發優于多線程并發。計算密集型程序指的程序的運行時間大部分消耗在CPU的運算處理過程,而硬盤和內存的讀寫消耗的時間很短;相對地,IO密集型程序指的則是程序的運行時間大部分消耗在硬盤和內存的讀寫上,CPU的運算時間很短。
對于多進程并發,python支持兩種實現方式,一種是采用進程安全的數據結構:multiprocessing.JoinableQueue,這種數據結構自己管理“加鎖”的過程,程序員無需擔心“死鎖”的問題;python還提供了一種更為優雅而高級的實現方式:采用進程池。下面一一介紹。
1.隊列實現——使用multiprocessing.JoinableQueue
multiprocessing是python標準庫中支持多進程并發的模塊,我們這里采用multiprocessing中的數據結構:JoinableQueue,它本質上仍是一個FIFO的隊列,它與一般隊列(如queue中的Queue)的區別在于它是多進程安全的,這意味著我們不用擔心它的互斥和死鎖問題。JoinableQueue主要可以用來存放執行的任務和收集任務的執行結果。舉例來看(以下皆省去導入包的過程):
def read(q): while True: try: value = q.get() print('Get %s from queue.' % value) time.sleep(random.random()) finally: q.task_done()def main(): q = multiprocessing.JoinableQueue() pw1 = multiprocessing.Process(target=read, args=(q,)) pw2 = multiprocessing.Process(target=read, args=(q,)) pw1.daemon = True pw2.daemon = True pw1.start() pw2.start() for c in [chr(ord('A')+i) for i in range(26)]: q.put(c) try: q.join() except KeyboardInterrupt: print("stopped by hand")if __name__ == '__main__': main()對于windows系統的多進程并發,程序文件里必須含有“入口函數”(如main函數),且結尾處必須調用入口點。例如以if __name__ == '__main__': main()結尾。
在這個最簡單的多進程并發例子里,我們用多進程實現將26個字母打印出來。首先定義一個存放任務的JoinableQueue對象,然后實例化兩個Process對象(每個對象對應一個子進程),實例化Process對象需要傳送target和args參數,target是實現每個任務工作中的具體函數,args是target函數的參數。
|
新聞熱點
疑難解答