python - 如何处理在 Python 中并行运行的子进程的用户输入?

标签 python multithreading python-3.x parallel-processing popen

我有一个 Python 辅助函数来并行运行 grunt 命令,使用 Popen 来处理子进程。目的是通过 CLI 进行通信。当所有这些过程需要任何用户输入时,问题就开始了,例如文件路径、密码、“是/否”决定:

Enter file path: Enter file path: Enter file path: Enter file path: Enter file path: Enter file path: Enter file path: 
Everything up-to-date
Grunt task completed successfully.

用户提供一次输入,一个进程成功完成,所有其他进程永远不会完成执行。

代码:

from subprocess import check_output, Popen

def run_grunt_parallel(grunt_commands):

    return_code = 0

    commands = []
    for command in grunt_commands:
        with tempfile.NamedTemporaryFile(delete=False) as f:
            app = get_grunt_application_name(' '.join(command))
            commands.append({'app': app, 'process': Popen(command, stdout=f)})

    while len(commands):
        sleep(5)
        next_round = []
        for command in commands:
            rc = command['process'].poll()
            if rc == None:
                next_round.append(command)
            else:
                if rc == 0:
                else:
                    return_code = rc

        commands = next_round

    return return_code

有没有办法确保用户可以为每个流程提供所有必要的输入?

最佳答案

您想要的几乎(如果不是完全)不可能。但是,如果您能够以无前缀的方式识别提示(并且,如果它有所不同,从中知道他们期望输入多少行),您应该能够管理它。

使用双向无缓冲管道运行每个进程:

Popen(command, stdin=subprocess.PIPE,
      stdout=f, stderr=subprocess.PIPE, bufsize=0)

(行为良好的程序会提示标准错误。您的程序似乎会这样做,因为尽管有 stdout=f,您还是显示了提示;如果它们不可靠,您可以阅读同样来自管道,在其中搜索提示,然后自己将其复制到文件中。)

Unix

将所有管道设置为非阻塞。然后使用 select 监控所有进程的 stderr 管道。 (您可以尝试使用 selectors。)缓冲您为每个进程分别读取的内容,直到您识别出来自一个进程的提示。然后显示提示(标识源进程)并接受来自用户的输入——如果提示之间的输出适合管道缓冲区,这不会减慢后台工作。将该用户输入放入与该进程关联的缓冲区中,并将其 stdin 管道添加到 select

stdin 管道显示准备就绪时,写入它,并在完成后将其从集合中移除。当从管道读取返回 EOF 时,加入 相应的进程(或者如果您担心进程可能提前结束,则在 SIGCHLD 处理程序中这样做)。

window

除非你有一个支持管道的可用的select 仿真,否则你将不得不使用线程——每个进程一个,或者如果一个进程可能在编写提示后产生输出,则每个管道一个在阅读回复之前。然后使用 Queue 将提示作为消息发送到主线程,然后主线程可以使用(例如)另一个每进程 Queue 将用户输入发送回线程(或其写作伙伴)。

这适用于任何支持线程的平台,并且具有不依赖管道缓冲区以避免拖延多话进程的潜在优势。

关于python - 如何处理在 Python 中并行运行的子进程的用户输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49857892/

相关文章:

python - Pandas 在后续行和分组依据上应用 if 条件

c - pthread 程序中例程的额外执行时间花费了什么?

python - 踢掉所有命令

python - 我们如何在 Python 中动态地将嵌套 XML 转换为 CSV,嵌套 XML 也可能包含值数组?

python - 覆盖范围未显示 virtualenv 中执行的行

python - 使用 perl 或 python 更改文本

c++ - thread-local static uniform_int_distribution,是否会针对不同的min、max集合重新创建?

c++ - 如果并行执行,磁盘文件操作是否更快?

python - 重载 __getitem__ 接受另一个参数

python-3.x - 从两个不同的数据集创建一个数据集