在 Python 中并行输入运行可执行文件

问题描述 投票:0回答:1

我有一个程序需要运行多个可执行文件,我想通过并行运行这些文件来提高性能。

我的基本代码看起来像这样:

import subprocess

def run_exe(input_command):
    p = subprocess.Popen('example.exe',stdin=subprocess.PIPE,stdout=subprocess.PIPE)
    p.communicate(bytes(input_command,'utf-8'))

if __name__ == '__main__':
    run_exe('task_1')
    run_exe('task_2')

我想要多线程或多处理它,但是当我这样做时它不起作用。我检查了 stdout,看起来 p.communicate 发送的 input_command 没有被确认(stdout 有一个“等待输入”消息)。我在网上看到一个模糊的参考资料,其中提到 p.communicate 可能只能在主进程上正常工作,但海报没有提供任何其他详细信息来说明原因或任何潜在的解决方法。这是我要实现的多线程代码的示例:

import subprocess
import threading

def run_exe(input_command):
    p = subprocess.Popen('example.exe',stdin=subprocess.PIPE,stdout=subprocess.PIPE)
    p.communicate(bytes(input_command,'utf-8'))

if __name__ == '__main__':
    t1 = threading.Thread(run_exe,('task_1',))
    t2 = threading.Thread(run_exe,('task_2',))
    t1.start()
    t2.start()
    t1.join()
    t2.join()

但如上所述,可执行文件未正确接收输入。

python multithreading multiprocessing subprocess executable
1个回答
0
投票

我建议使用

concurrent.futures
,它是一个包装器,比直接使用线程更简单。

import concurrent.futures
import logging
import subprocess


def run_exe(input_command: str):
    process = subprocess.run(
        ["example.exe"],
        input=input_command,
        text=True,
        stdout=subprocess.PIPE,
    )
    return process.stdout


def main():
    logging.basicConfig(
        level=logging.DEBUG,
        format="%(asctime)s | %(levelname)-8s | %(threadName)-24s | %(message)s",
        datefmt="%H:%M:%S",
    )
    logging.info("Start")

    with concurrent.futures.ThreadPoolExecutor() as executor:
        output = [(arg, executor.submit(run_exe, arg)) for arg in ["task_1", "task_2"]]

    for arg, future in output:
        logging.info("%s --> %s", arg, future.result())

    logging.info("End")


if __name__ == "__main__":
    main()

输出:

11:16:12 | INFO     | MainThread               | Start
11:16:15 | INFO     | MainThread               | task_1 --> Output for task_1
11:16:15 | INFO     | MainThread               | task_2 --> Output for task_2
11:16:15 | INFO     | MainThread               | End

注释

  • 我使用
    subprocess.run()
    ,强烈推荐它而不是
    Popen
    • Set
      input=input_command
      是我向进程发送文本的方式' stdin
    • 设置
      text=True
      ,这样我就不必对输入/输出进行编码/解码
  • 我用
    ThreadPoolExecutor
    启动了一个线程池,我也可以使用
    ProcessPoolExecutor
    ,因为它们具有相同的接口
    • output
      是(输入,未来)
    • 的列表
    • 当我退出
      with
      语句时,我可以确定所有任务都已完成
© www.soinside.com 2019 - 2024. All rights reserved.