[英]Python concurrent.futures using subprocess, running several python script
我想使用current.futures同時運行多個python腳本。 我的代碼的串行版本去查找文件夾中的特定python文件並執行它。
import re
import os
import glob
import re
from glob import glob
import concurrent.futures as cf
FileList = [];
import time
FileList = [];
start_dir = os.getcwd();
pattern = "Read.py"
for dir,_,_ in os.walk(start_dir):
FileList.extend(glob(os.path.join(dir,pattern))) ;
FileList
i=0
for file in FileList:
dir=os.path.dirname((file))
dirname1 = os.path.basename(dir)
print(dirname1)
i=i+1
Str='python '+ file
print(Str)
completed_process = subprocess.run(Str)`
對於我的代碼的並行版本:
def Python_callback(future):
print(future.run_type, future.jid)
return "One Folder finished executing"
def Python_execute():
from concurrent.futures import ProcessPoolExecutor as Pool
args = FileList
pool = Pool(max_workers=1)
future = pool.submit(subprocess.call, args, shell=1)
future.run_type = "run_type"
future.jid = FileList
future.add_done_callback(Python_callback)
print("Python executed")
if __name__ == '__main__':
import subprocess
Python_execute()
問題是我不確定如何將FileList的每個元素傳遞給單獨的cpu
謝謝您的幫助
最小的更改是對每個元素使用一次submit
,而不是對整個列表使用一次:
futures = []
for file in FileList:
future = pool.submit(subprocess.call, file, shell=1)
future.blah blah
futures.append(future)
僅當您要對期貨執行某些操作時才需要futures
列表,例如等待它們完成,檢查其返回值等。
同時,您正在使用max_workers=1
顯式創建池。 毫不奇怪,這意味着您只會得到1個輔助子進程,因此它將最終等待一個子進程完成,然后再獲取下一個子進程。 如果要實際同時運行它們,請刪除該max_workers
並將其默認為每個內核一個(或通過max_workers=8
或其他一些不為1
(如果有充分的理由覆蓋默認值))。
在進行此操作時,有很多方法可以簡化您的工作:
multiprocessing
嗎? 如果您需要與每個子流程進行通信,那么在單個線程中執行該操作可能會很痛苦,但是線程或asyncio
工作原理與此處的流程一樣好。 shell=1
而不是僅僅傳遞一個列表而不使用shell? 使用外殼不必要地產生了開銷,安全問題和調試煩惱。 jid
每個未來它只是所有調用的字符串,不能是有用的列表。 可能更有用的是某種標識符或子流程的返回代碼,或者……可能還有很多其他事情,但這些都是可以通過讀取subprocess.call
的返回值或簡單的包裝器來完成的。 as_completed
,則可以更簡單地顯示結果。 pool.submit
,則循環內只剩下一個pool.submit
了,這意味着您可以用pool.map
替換整個循環。 os.walk
和glob
混合使用。 當您實際上具有全局模式時,將fnmatch
應用於os.walk
的files
列表。 但是在這里,您只是在每個目錄中查找特定的文件名,因此,實際上,您需要過濾的只是file == 'Read.py'
。 i
。 但是,如果確實需要,最好for i, file in enumerate(FileList):
執行for i, file in enumerate(FileList):
for file in FileList:
而不要for file in FileList:
然后手動增加i
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.