Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在for循环中使用subprocess.Popen?_Python_Python 3.x_Subprocess_Benchmarking - Fatal编程技术网

Python 如何在for循环中使用subprocess.Popen?

Python 如何在for循环中使用subprocess.Popen?,python,python-3.x,subprocess,benchmarking,Python,Python 3.x,Subprocess,Benchmarking,我试图使用subprocess.Popen来运行命令,我选择了subprocess.run,因为我需要将命令的输出打印到shell中 我在for循环中调用这些命令,并为每次迭代修改环境,但是python只运行第一个命令,而不运行其他6个命令 我很确定这是一个bug,因为我找不到其他类似的东西,但我想在提交“bug”之前我会检查一下 相关代码如下所示 input_file = Path("input.json").open() for thread in threads:

我试图使用subprocess.Popen来运行命令,我选择了subprocess.run,因为我需要将命令的输出打印到shell中

我在for循环中调用这些命令,并为每次迭代修改环境,但是python只运行第一个命令,而不运行其他6个命令

我很确定这是一个bug,因为我找不到其他类似的东西,但我想在提交“bug”之前我会检查一下

相关代码如下所示

input_file = Path("input.json").open()

for thread in threads:
    new_env = default_env
    new_env["OMP_NUM_THREADS"] = str(thread)
    print("Starting run for {} threads".format(thread))
    process = subprocess.Popen(
        benchmark_command, env=new_env, stdin=input_file, stdout=subprocess.PIPE)
    lines = []
    for line in process.stdout:
        print(line.decode(), end='')
    results.append(Result(lines, thread))
    print("Completed run for {} threads".format(thread))
❯ python python/plot_results.py
Starting run for 1 threads
<expected output from running command>
Completed run for 1 threads
Starting run for 2 threads
<expected output from running command>
Completed run for 2 threads
Starting run for 4 threads
<expected output from running command>
Completed run for 4 threads
Starting run for 8 threads
<expected output from running command>
Completed run for 8 threads
Starting run for 16 threads
<expected output from running command>
Completed run for 16 threads
Starting run for 32 threads
<expected output from running command>
Completed run for 32 threads
Starting run for 56 threads
<expected output from running command>
Completed run for 56 threads
电流输出是这样的

❯ python python/plot_results.py
Starting run for 1 threads
<expected output from running command>
Completed run for 1 threads
Starting run for 2 threads
Completed run for 2 threads
Starting run for 4 threads
Completed run for 4 threads
Starting run for 8 threads
Completed run for 8 threads
Starting run for 16 threads
Completed run for 16 threads
Starting run for 32 threads
Completed run for 32 threads
Starting run for 56 threads
Completed run for 56 threads
❯ python/plot_results.py
开始运行1个线程
已完成1个线程的运行
开始运行2个线程
已完成2个线程的运行
开始运行4个线程
已完成4个线程的运行
开始运行8个线程
已完成8个线程的运行
开始运行16个线程
已完成16个线程的运行
开始运行32个线程
已完成32个线程的运行
开始运行56个线程
已完成56个线程的运行
但应该是这样的

input_file = Path("input.json").open()

for thread in threads:
    new_env = default_env
    new_env["OMP_NUM_THREADS"] = str(thread)
    print("Starting run for {} threads".format(thread))
    process = subprocess.Popen(
        benchmark_command, env=new_env, stdin=input_file, stdout=subprocess.PIPE)
    lines = []
    for line in process.stdout:
        print(line.decode(), end='')
    results.append(Result(lines, thread))
    print("Completed run for {} threads".format(thread))
❯ python python/plot_results.py
Starting run for 1 threads
<expected output from running command>
Completed run for 1 threads
Starting run for 2 threads
<expected output from running command>
Completed run for 2 threads
Starting run for 4 threads
<expected output from running command>
Completed run for 4 threads
Starting run for 8 threads
<expected output from running command>
Completed run for 8 threads
Starting run for 16 threads
<expected output from running command>
Completed run for 16 threads
Starting run for 32 threads
<expected output from running command>
Completed run for 32 threads
Starting run for 56 threads
<expected output from running command>
Completed run for 56 threads
❯ python/plot_results.py
开始运行1个线程
已完成1个线程的运行
开始运行2个线程
已完成2个线程的运行
开始运行4个线程
已完成4个线程的运行
开始运行8个线程
已完成8个线程的运行
开始运行16个线程
已完成16个线程的运行
开始运行32个线程
已完成32个线程的运行
开始运行56个线程
已完成56个线程的运行

首先,我想说的是,除非您在该语言方面的专业水平远远超过了高级水平,或者您的问题的性质非常罕见,否则您的问题不太可能是一个bug,而可能是您对该语言的工作方式有一些误解

在您的情况下,
Popen
不会阻塞主线程。您的问题是主线程正在启动所有进程。。。最终开始从标准输出读取输出并打印

简单的解决方案是使用
子进程。检查\u output
以等待命令完成,但它不允许
env
参数,因此我们将在调用Popen后使用
communicate()
方法,这也将阻塞主线程并等待进程终止:

对于线程中的线程:
新建环境=默认环境
new_env[“OMP_NUM_THREADS”]=str(thread)
打印(“开始运行{}个线程”。格式化(线程))
输出=子流程.Popen(
benchmark_命令,env=new_env,stdin=input_file,stdout=subprocess.PIPE)
stdout,stderr=output.communicate()
行=[]
对于标准输出中的行:
打印(line.decode(),end='')
results.append(结果(行、线程))
打印(“为{}个线程完成运行”。格式化(线程))

根据@jasonharper的建议,我需要为每次迭代创建一个新的openfile对象

input_file = Path("input.json")

for thread in threads:
    new_env = default_env
    new_env["OMP_NUM_THREADS"] = str(thread)
    print("Starting run for {} threads".format(thread))
    process = subprocess.Popen(
        benchmark_command, env=new_env, stdin=input_file.open(), stdout=subprocess.PIPE)
    lines = []
    for line in process.stdout:
        print(line.decode(), end='')
    results.append(Result(lines, thread))
    print("Completed run for {} threads".format(thread))

input_file
可能是一个打开的文件对象。子流程的第一次运行可能会消耗掉所有的子流程,将文件放在最后。后续运行将没有可处理的输入数据。@jasonharper谢谢,就这样!我没有从benchmark命令中得到任何错误的原因是它打开了一个输入流,并且没有超时。