首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在python中使用池进行多处理?

在python中使用池进行多处理?
EN

Stack Overflow用户
提问于 2022-08-17 07:59:03
回答 1查看 127关注 0票数 0

我正在用Tkinter编写一个小应用程序,以与没有GUI的现有可执行文件进行交互。可执行文件可以将Solid Edge文件导出为不同格式(例如PDF格式)。(请参见www上的Solid Edge翻译服务)。目标是将文件批量导出到PDF。

因此,调用可执行文件的代码部分就在这里。我需要多处理,因为运行可执行文件需要一段时间,这将使我的应用程序没有响应。

代码语言:javascript
运行
复制
    for cmd in commands: 
        print(f'running cmd {cmd}')
        p = Process(target=exportSingleFile, args=(cmd,))
        p.start()

(命令=带有输入和输出文件参数和输出文件类型(pdf)的命令列表(作为字符串) )。就像这样:

代码语言:javascript
运行
复制
"C:/Program Files/Solid Edge ST9/Program/SolidEdgeTranslationServices.exe" -i="input file" -o="output file" -t=pdf"

但是当我试图用这个代替它的时候,我的应用程序似乎变得反应迟钝,什么也没有发生。我想,在导出可能的几十个文件时,最好使用池。

代码语言:javascript
运行
复制
    exportResult = []
    with Pool() as pool:
        exportResult = pool.imap_unordered(exportSingleFile,commands)
    for r in exportResult: 
        print (r)

这就是"exportsinglefile“所做的。

代码语言:javascript
运行
复制
def exportSingleFile(cmd):
    return subprocess.run(cmd, shell=True)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-17 08:25:00

multiprocessing模块主要用于运行多个并行Python进程。由于您的命令已经作为单独的进程运行,因此在此基础上使用multiprocessing是多余的。

相反,考虑直接使用subprocess.Popen构造函数,它启动子进程,但不等待它完成。将这些进程对象存储在列表中。然后,您可以定期对列表中的每个进程进行poll(),以查看它是否完成。要安排这样的投票,请使用Tkinter的after函数。

这样一个实现的粗略草图--您需要根据您的情况调整它,而我没有测试它:

代码语言:javascript
运行
复制
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个命令:

代码语言:javascript
运行
复制
commands = ParallelCommands(["ls /bin", "ls /lib"], 10)

为了同步等待完成,阻塞UI;只是为了演示目的:

代码语言:javascript
运行
复制
while not commands.is_done():
    commands.poll()
    time.sleep(0.1)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73384812

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档