簡體   English   中英

在 python 中使用池進行多處理?

[英]multiprocessing with a Pool in python?

我正在編寫一個帶有 Tkinter GUI 的小型應用程序,以與沒有 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()

(命令 = 帶有 arguments 輸入和 output 文件和 output 文件類型(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)

multiprocessing模塊主要用於運行多個並行Python進程。 由於您的命令已經作為單獨的進程運行,因此在此之上使用multiprocessing是多余的。

相反,請考慮直接使用subprocess.Popen構造函數,它啟動子進程但不等待它完成。 將這些過程對象存儲在一個列表中。 然后,您可以定期poll()列表中的每個進程以查看它是否已完成。 要安排這樣的投票,請在 function after使用 Tkinter。

這種實現的粗略草圖——你需要根據你的情況來調整它,我沒有測試它:

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 not 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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM