理解Python中程序和執行緒模組

2022-07-07 22:54:18 字數 2777 閱讀 4801

工作上剛好遇到需要用多程序方法提高程式執行效率的問題,梳理一下如何使用python中線程(threading),子程序(subprocess)和多程序(multiprocessing)模組來實現併發/並行操作,提高**效率。本文重在比較各模組的適用場景,每個模組的用法只做簡單概述。

1,執行緒和程序的區別是什麼?

簡言之,乙個任務就是乙個程序,而執行緒是任務中最小執行單元。多個執行緒可以存在於同乙個程序之中,同乙個程序裡的執行緒之間共享同一塊記憶體區域(這意味著不同執行緒可能會讀寫同乙個變數,執行緒彼此干擾)。程序不共享記憶體,程序間的互動需要通過其他方式(如files,pipes 或 sockets)。

多執行緒程式設計的優點在於執行緒建立和管理比程序更快,執行緒內通訊速度也更快,執行緒的缺點在於執行緒有相互干擾風險,需要保證共享資料有序地修改,程式設計難度更大

2, python gil全域性直譯器鎖概述

gil全稱global interpreter lock,中文名:全域性直譯器鎖。python**的執行由python主直譯器(最常見的為cpython)來控制。gil控制著python直譯器的訪問許可權,從而保證同一時刻只有乙個執行緒在執行。

每個執行緒執行前需先獲取gil,在跑多執行緒的情況下,始終只有乙個執行緒在cpu上執行。因此python通常只能發揮單核的功能,程式效率並不高。

3,多程序mutilprocessing

mutilprocessing包支援在python程式中啟動新的程序,很大程度上可以彌補因gil導致的程式低效,因為每個程序使用獨立的gil,在多核cpu上可以並行多個程序。

最基礎的用法是通過multiprocessing.process物件建立乙個新程序:

p = multiprocessing.process( target=none, args=())  #建立程序,target引數傳入可呼叫的函式,通過args為該函式傳參

p.start()  #啟動程序

p.join()  #等待程序結束

如果需要建立多個子程序,可以採用程序池,pool返回的是程序的集合,適合對程序進行批量處理:

pl=multiprocessing.pool(processes=none) #建立程序池,processes為程序數量,如果為none,則使用os.cpu_count()返回值

pl.map(func, iterable)   #批量執行子程序func

pl.close() #關閉程序池,關閉後不能往pool中增加新的子程序

pl.join()  #等待程序池中的子程序執行完畢,需在close()後呼叫

如果多程序間需要資料通訊,我們可以用multiprocessing.manager:

manager= multiprocessing.manager()  #

建立共享資料物件

m_list=manager.list()     #設定列表共享物件

m_dict=manager.dict()  #設定字典共享物件

4, 子程序庫subprocess

同樣是關於建立子程序的模組,subprocess和multiprocessing的區別在於,前者更適用執行外部的程式或命令列(multiprocessing其實也能呼叫外部程式,只是由於機制不同,會比subprocess更占用資源),後者更適合呼叫當前檔案內的某個函式作為子程序

subprocess模組中程序的建立與管理是通過popen類來實現:

p = subprocess.popen(args)   #啟動子程序,args表示要執行的命令

p.wait()  #等待子程序結束

基於popen的封裝subprocess裡還提供了其他建立子程序的方法,如subprocess.run()用法和直接popen差不多,主要區別在於無需用wait()來等待子程序完成。此外popen支援的引數更多,以滿足各種複雜的子程序使用場景。

5,執行緒庫threading

什麼場景應該使用多執行緒,什麼場景更適合多程序?如果你的程式需要長時間等待資料傳輸,適用多執行緒。如果你的程式時間開銷主要用於cpu計算,則適合多程序。因為採用了相似的應用程式介面,執行緒的構造和使用的語法和multiprocessing中的程序非常相似:

t= thread( target=none, args=())    #建立執行緒,target引數定義執行緒呼叫的函式,通過args為該函式傳參

t.start() #啟動執行緒

t.join()  #等待執行緒結束

為了操作同一塊記憶體中的資源不產生衝突,執行緒模組中還提供了鎖rlock:

lock = threading.rlock()

lock.acquire()  #獲得鎖。執行緒進入同步阻塞狀態

#中間可以進行資料操作

lock.release()  #釋放鎖

6,總結

多程序模組很好地補償了python中gil機制對程式效能的限制,可以讓我們充分使用多核cpu資源;多執行緒模組適用於優化需要長時間資料傳輸/檔案讀寫的程式(如爬蟲)。合理使用上述方法可以幫助我們寫出更高效的程式。

***環境為win10上的python3.7.4

Python中程序執行緒協程小結

程式僅僅只是一堆 而已,而程序指的是程式的執行過程。需要強調的是 同乙個程式執行兩次,那也是兩個程序。程序 資源管理單位 容器 執行緒 最小執行單位,管理執行緒的是程序。程序就是乙個程式在乙個資料集上的一次動態執行過程。程序一般由程式 資料集 程序控制塊三部分組成。我們編寫的程式 用來描述程序要完成...

Python執行緒和程序join 理解

import threading import time def run time.sleep 2 print 當前執行緒名字 threading.current thread name time.sleep 2 if name main start time time.time print 主線程...

android中程序和執行緒的概述

在預設的情況下所有的應用的元件都是執行在同乙個程序中的,當然在某種特別耗時的動作中也可以指定新的程序。指定新程序可以通過android process屬性 在系統資源不足時會根據程序級別的不同kill掉執行緒,下面介紹一下程序的級別 乙個activity使用者正在互動 在呼叫onresume方法後 ...