我正在用Tkinter编写一个小应用程序,以与没有GUI的现有可执行文件进行交互。可执行文件可以将Solid Edge文件导出为不同格式(例如PDF格式)。(请参见www上的Solid Edge翻译服务)。目标是将文件批量导出到PDF。
因此,调用可执行文件的代码部分就在这里。我需要多处理,因为运行可执行文件需要一段时间,这将使我的应用程序没有响应。
for cmd in commands:
print(f'running cmd {cmd}')
p = Process(target=exportSingleFile, args=(cmd,))
p.start()
(命令=带有输入和输出文件参数和输出文件类型(pdf)的命令列表(作为字符串) )。就像这样:
"C:/Program Files/Solid Edge ST9/Program/SolidEdgeTranslationServices.exe" -i="input file" -o="output file" -t=pdf"
但是当我试图用这个代替它的时候,我的应用程序似乎变得反应迟钝,什么也没有发生。我想,在导出可能的几十个文件时,最好使用池。
exportResult = []
with Pool() as pool:
exportResult = pool.imap_unordered(exportSingleFile,commands)
for r in exportResult:
print (r)
这就是"exportsinglefile“所做的。
def exportSingleFile(cmd):
return subprocess.run(cmd, shell=True)
发布于 2022-08-17 08:25:00
multiprocessing
模块主要用于运行多个并行Python进程。由于您的命令已经作为单独的进程运行,因此在此基础上使用multiprocessing
是多余的。
相反,考虑直接使用subprocess.Popen
构造函数,它启动子进程,但不等待它完成。将这些进程对象存储在列表中。然后,您可以定期对列表中的每个进程进行poll()
,以查看它是否完成。要安排这样的投票,请使用Tkinter的after
函数。
这样一个实现的粗略草图--您需要根据您的情况调整它,而我没有测试它:
class ParallelCommands:
def __init__(self, commands, num_parallel):
self.commands = commands[::-1]
self.num_parallel = num_parallel
self.processes = []
self.poll()
def poll(self):
# Poll processes for completion, and raise on errors.
for process in self.processes:
process.poll()
if process.returncode is not None and process.returncode != 0:
raise RuntimeError("Process finished with nonzero exit code")
# Remove completed processes.
self.processes = [
p for p in self.processes
if p.returncode is None
]
# Start new processes up to the maximum amount.
while self.commands and len(self.processes) < self.num_parallel:
command = self.commands.pop()
process = subprocess.Popen(command, shell=True)
self.processes.push(process)
def is_done(self):
return not self.processes and not self.commands
要启动多个命令,最多同时运行10个命令:
commands = ParallelCommands(["ls /bin", "ls /lib"], 10)
为了同步等待完成,阻塞UI;只是为了演示目的:
while not commands.is_done():
commands.poll()
time.sleep(0.1)
https://stackoverflow.com/questions/73384812
复制相似问题