[英]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.