Python併發解決方案
一、subprocess模組
call():執行命令,返回程式返回碼(int)
import subprocess
print(subprocess.call("mspaint"))
check_output():執行命令,返回輸出(bytes)
import subprocess
import chardet
output = subprocess.check_output("ipconfig")
encoding = chardet.detect(output)['encoding']
print(output.decode(encoding, errors="ignore"))
二、threading模組
Thread
建構函式-引數:
target: 執行的操作(可呼叫物件,必選的)
name: 執行緒名(字串,可選的)
args: 可呼叫物件需要的引數(位置引數部分,元組)
kwargs: 可呼叫物件需要的引數(關鍵字引數部分,字典)
from threading import Thread
t = Thread(
target=print,
args=(1, 2, 3),
kwargs={'sep': '->', 'end': '\n' * 10}
)
t.start()
方法:
start(): 啟動執行緒(開始交給CPU執行)
run():start()啟動之後,會被自動呼叫的方法。(子類可重寫)
join(): 讓父級執行緒等待自己完成(必須要在呼叫start()之後才能呼叫)
屬性:
name:執行緒名稱
daemon:是否是後臺執行緒(若要設定該值,必須要在呼叫start()方法之前)
ident: 執行緒ID
Event:
set(): 設定值為True
clear(): 設定值為False
wait(): 等待
is_set():判斷值是否為True
函式:
main_thread():得到主執行緒物件
active_count():得到活躍執行緒數目
current_thread():得到當前所在的執行緒物件
enumerate():返回迭代器,得到所有的活躍執行緒
關於daemon:
在指令碼執行過程中有一個主執行緒,若在主執行緒中建立了子執行緒,當主執行緒結束時根據子執行緒daemon屬性值的不同可能會發生下面的兩種情況之一:
如果某個子執行緒的daemon屬性為False,主執行緒結束時會檢測該子執行緒是否結束,如果該子執行緒還在執行,則主執行緒會等待它完成後再退出;
如果某個子執行緒的daemon屬性為True,主執行緒執行結束時不對這個子執行緒進行檢查而直接退出,同時所有daemon值為True的子執行緒將隨主執行緒一起結束,而不論是否執行完成。
屬性daemon的值預設為False,如果需要修改,必須在呼叫start()方法啟動執行緒之前進行設定。
另外要注意的是,上面的描述並不適用於IDLE環境中的互動模式或指令碼執行模式,因為在該環境中的主執行緒只有在退出Python IDLE時才終止。
三、multiprocessing模組
Process() 建立一個程序物件,建構函式引數如下
target:要執行的操作(函式)(必須)
name:程序名(可選)
args:傳遞給target的函式執行時需要的位置、可選引數(按位置指定)
kwargs:傳遞給target的函式執行時需要的關鍵字引數(按名稱指定)
程序物件(例項)方法:
start():啟動程序
run():程序啟動後,實際執行的方法,一般重寫此方法。
terminate():強制結束程序
join():等待所有子程序執行完成
程序物件(例項)屬性:
name:程序名
daemon:是否是後臺程序
pid: 程序id
Pool(),建立一個程序池,建構函式引數(都是可選的)如下:
numprocess:程序池大小(同時有幾個程序在工作)(預設為當前電腦的CPU核心數)
initializer:每個程序啟動時執行的操作(函式)
initargs:傳遞給initializer的函式執行需要的引數(元組)
Pool物件方法:
執行方法:
apply(func, args, kwargs):(同步)執行一個。(返回值,func的返回結果)
apply_async(func, args, kwargs):(非同步)執行一個。(返回值:ApplyResult,與AsyncResult類似,需要在程序池中所有任務完成後呼叫其get()方法取資料)
map(func,iterable, chunksize):(同步)一次取N個放到程序池中執行(N為程序池大小),等到本次取出的都執行完了再取下一批。(返回值:list,與外部資料順序一致)
map_async(func,iterable, chunksize):(非同步)一次取N個放到程序池中執行(N為程序池大小),只要程序池中有空閒位置,就取會資料,保證程序池一直是忙碌的。(返回值: AsyncResult,需要在程序池中所有任務完成後呼叫其get()方法取資料)
imap(func, iterable, chunksize):與map()類似,返回可迭代物件,返回資料的順序和外部傳遞的資料順序一致。
imap_unordered(func, iterable, chunksize):與map()類似,但是返回資料的順序不能確定(當對資料順序沒有要求時使用)。
程序池管理方法():
close():關閉程序池,但是會等待池中作業完成
terminate():停止程序池中的作業,會關閉程序池
join():等待程序池中所有任務完成(需要先關閉程序池)
AsyncResult方法:
get(timeout):timeout可選。獲取結果
ready():判斷程序池中任務是否執行完畢。
successful():判斷程序池中任務是否都正常完成了(只要有一個程序出錯了,就會返回False)。
wait(timeout):timeout可選。
Manager()託管物件。
dict(): 共享字典
Event(): 共享事件
list(): 共享列表
Value(typecode, value): 共享的單個值
multiprocessing.dummy.Pool() 執行緒池:
from multiprocessing.dummy import Pool as ThreadPool
pool_size = 4 # 執行緒池大小
tpool = ThreadPool(pool_size) # 建立執行緒池
程序池有的方法,執行緒池都有。
獲取CPU核心數:
標準庫- multiprocessingimport multiprocessing
multiprocessing.cpu_count()
第三方- psutilimport psutil
psutil.cpu_count()
注意:Python中的多程序,啟動程式碼需要在if__name__ == "__main__"中,多程序程式碼,不能在互動式環境中執行,應該使用python xxx.py的方式執行。
參考:17.2. multiprocessing — Process-based parallelism
附加:
numpy
.mean():求平均值
.sum(): 求和
uuid
uuid4():生成唯一id(UUID型別,可以通過str()轉成字串)
1. subprocess模組
2. threading模組
3. multiprocessing模組
一、 subprocess模組
call():執行命令,返回程式返回碼(int)
import subprocess
print(subprocess.call("mspaint")) |
check_output():執行命令,返回輸出(bytes)
import subprocess import chardet
output = subprocess.check_output("ipconfig") encoding = chardet.detect(output)['encoding'] print(output.decode(encoding, errors="ignore")) |
二、 threading模組
Thread
建構函式-引數:
n target: 執行的操作(可呼叫物件,必選的)
n name: 執行緒名(字串,可選的)
n args: 可呼叫物件需要的引數(位置引數部分,元組)
n kwargs: 可呼叫物件需要的引數(關鍵字引數部分,字典)
from threading import Thread
t = Thread( target=print, args=(1, 2, 3), kwargs={'sep': '->', 'end': '\n' * 10} )
t.start() |
方法:
n start(): 啟動執行緒(開始交給CPU執行)
n run():start()啟動之後,會被自動呼叫的方法。(子類可重寫)
n join(): 讓父級執行緒等待自己完成(必須要在呼叫start()之後才能呼叫)
屬性:
n name:執行緒名稱
n daemon:是否是後臺執行緒(若要設定該值,必須要在呼叫start()方法之前)
n ident: 執行緒ID
Event:
n set(): 設定值為True
n clear(): 設定值為False
n wait(): 等待
n is_set():判斷值是否為True
函式:
n main_thread():得到主執行緒物件
n active_count():得到活躍執行緒數目
n current_thread():得到當前所在的執行緒物件
n enumerate():返回迭代器,得到所有的活躍執行緒
關於daemon:
在指令碼執行過程中有一個主執行緒,若在主執行緒中建立了子執行緒,當主執行緒結束時根據子執行緒daemon屬性值的不同可能會發生下面的兩種情況之一:
l 如果某個子執行緒的daemon屬性為False,主執行緒結束時會檢測該子執行緒是否結束,如果該子執行緒還在執行,則主執行緒會等待它完成後再退出;
l 如果某個子執行緒的daemon屬性為True,主執行緒執行結束時不對這個子執行緒進行檢查而直接退出,同時所有daemon值為True的子執行緒將隨主執行緒一起結束,而不論是否執行完成。
屬性daemon的值預設為False,如果需要修改,必須在呼叫start()方法啟動執行緒之前進行設定。
另外要注意的是,上面的描述並不適用於IDLE環境中的互動模式或指令碼執行模式,因為在該環境中的主執行緒只有在退出Python IDLE時才終止。
三、 multiprocessing模組
Process() 建立一個程序物件,建構函式引數如下
u target:要執行的操作(函式)(必須)
u name:程序名(可選)
u args:傳遞給target的函式執行時需要的位置、可選引數(按位置指定)
u kwargs:傳遞給target的函式執行時需要的關鍵字引數(按名稱指定)
程序物件(例項)方法:
n start():啟動程序
n run():程序啟動後,實際執行的方法,一般重寫此方法。
n terminate():強制結束程序
n join():等待所有子程序執行完成
程序物件(例項)屬性:
n name:程序名
n daemon:是否是後臺程序
n pid: 程序id
Pool(),建立一個程序池,建構函式引數(都是可選的)如下:
u numprocess:程序池大小(同時有幾個程序在工作)(預設為當前電腦的CPU核心數)
u initializer:每個程序啟動時執行的操作(函式)
u initargs:傳遞給initializer的函式執行需要的引數(元組)
Pool物件方法:
執行方法:
n apply(func, args, kwargs):(同步)執行一個。(返回值,func的返回結果)
n apply_async(func, args, kwargs):(非同步)執行一個。(返回值:ApplyResult,與AsyncResult類似,需要在程序池中所有任務完成後呼叫其get()方法取資料)
n map(func,iterable, chunksize):(同步)一次取N個放到程序池中執行(N為程序池大小),等到本次取出的都執行完了再取下一批。(返回值:list,與外部資料順序一致)
n map_async(func,iterable, chunksize):(非同步)一次取N個放到程序池中執行(N為程序池大小),只要程序池中有空閒位置,就取會資料,保證程序池一直是忙碌的。(返回值: AsyncResult,需要在程序池中所有任務完成後呼叫其get()方法取資料)
n imap(func, iterable, chunksize):與map()類似,返回可迭代物件,返回資料的順序和外部傳遞的資料順序一致。
n imap_unordered(func, iterable, chunksize):與map()類似,但是返回資料的順序不能確定(當對資料順序沒有要求時使用)。
程序池管理方法():
u close():關閉程序池,但是會等待池中作業完成
u terminate():停止程序池中的作業,會關閉程序池
u join():等待程序池中所有任務完成(需要先關閉程序池)
AsyncResult方法:
l get(timeout):timeout可選。獲取結果
l ready():判斷程序池中任務是否執行完畢。
l successful():判斷程序池中任務是否都正常完成了(只要有一個程序出錯了,就會返回False)。
l wait(timeout):timeout可選。
Manager()託管物件。
n dict(): 共享字典
n Event(): 共享事件
n list(): 共享列表
n Value(typecode, value): 共享的單個值
multiprocessing.dummy.Pool() 執行緒池:
from multiprocessing.dummy import Pool as ThreadPool
pool_size = 4 # 執行緒池大小 tpool = ThreadPool(pool_size) # 建立執行緒池 |
程序池有的方法,執行緒池都有。
獲取CPU核心數:
標準庫- multiprocessing |
import multiprocessing
multiprocessing.cpu_count() |
第三方- psutil |
import psutil
psutil.cpu_count() |
注意:Python中的多程序,啟動程式碼需要在if__name__ == "__main__"中,多程序程式碼,不能在互動式環境中執行,應該使用python xxx.py的方式執行。
參考:17.2. multiprocessing — Process-based parallelism
附加:
numpy
.mean():求平均值
.sum(): 求和
uuid
uuid4():生成唯一id(UUID型別,可以通過str()轉成字串)