简体   繁体   English

如何使用 python 控制多个并发命令行程序?

[英]How can I use python to control multiple concurrant command line programs?

I'd like to use a python program to send different videos to different devices.我想使用 python 程序将不同的视频发送到不同的设备。

My plan is to use ffmpeg to control the video and the destination (I can do this for one destination using os.system) but I'm not sure how to write concurrent ffmpeg commands so that 6 videos are playing at the same time on different devices.我的计划是使用 ffmpeg 来控制视频和目标(我可以使用 os.system 为一个目标执行此操作)但我不确定如何编写并发 ffmpeg 命令以便 6 个视频同时在不同的播放设备。

Initially I thought I could use tmux but I can't find a solution for how to control/access different tmux windows within my python program.最初我以为我可以使用 tmux 但我找不到如何在我的 python 程序中控制/访问不同的 tmux windows 的解决方案。 Am I missing something obvious?我错过了一些明显的东西吗?

You can use the python subprocess module for that: https://docs.python.org/3/library/subprocess.html您可以为此使用 python 子进程模块: https://docs.python.org/3/library/subprocess.html

As a simple example, I will run a Linux utility 'sleep' which does nothing else than waiting for a given amount of seconds.作为一个简单的例子,我将运行一个 Linux 实用程序“sleep”,它除了等待给定的秒数外什么都不做。 I will do this in parallel to see that we can really do this with subprocess in parallel.我将并行执行此操作,以了解我们是否真的可以并行执行子流程。 As a first setup, I do:作为第一个设置,我这样做:

import os
import subprocess
import time

n_jobs = 5
sleeping_time_in_sec = 10
shell_command_with_arguments = ["sleep", f"{sleeping_time_in_sec}s"]

I'm importing 'subprocess' to launch jobs in parallel.我正在导入“子流程”以并行启动作业。 The 'time'module I'm going to use to measure the total running time.我将使用“时间”模块来测量总运行时间。 The 'os' module I'm going to use to block the script until all jobs are done.在完成所有作业之前,我将使用“os”模块来阻止脚本。 The shell command looks like 'sleep 10s', but for subprocess you put the script and all the arguments in a list. shell 命令看起来像“sleep 10s”,但对于子进程,您将脚本和所有 arguments 放在一个列表中。

Submit the jobs like this:像这样提交作业:

time_start = time.time()
jobs = list()
for counter in range(n_jobs):
    process = subprocess.Popen(shell_command_with_arguments, shell=False)
    jobs.append(process)

Now all the 5 jobs each taking 10 sec have been submitted.现在所有 5 个作业都已提交,每个作业耗时 10 秒。 In order to make your script wait until the last process is done, you can add:为了让你的脚本等到最后一个过程完成,你可以添加:

print(f"Waiting for all {n_jobs} processes to finish...")
for ip, process in enumerate(jobs):
    try:
        os.waitpid(process.pid, 0)
    except ChildProcessError:
        print(f"No more: {ip} : {process.pid}")
    else:
        print(f"DONE: {ip} : {process.pid}")

Finally, I report the total running time:最后,我报告总运行时间:

time_end = time.time()
delta_time = time_end - time_start
print(f"Run {n_jobs} jobs taking {sleeping_time_in_sec} s each in {delta_time} s")

The output of the script looks like:脚本的 output 如下所示:

Waiting for all 5 processes to finish...
DONE: 0 : 88988
DONE: 1 : 88989
DONE: 2 : 88990
DONE: 3 : 88991
DONE: 4 : 88992
Finished running 5 jobs each taking 10 s in 10.022365093231201 s

As you can see, if you would run the sleep command 5 times in serie, it would take 50 s.如您所见,如果连续运行 sleep 命令 5 次,则需要 50 秒。 But since the script took a little more then 10 s you can see the the jobs indeed were running in parallel.但是由于脚本花费了 10 秒多一点,您可以看到作业确实是并行运行的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM