如何关闭标准输出管终止进程开始与蟒蛇子POPEN什么时候?(How do I close the s

2019-09-01 05:53发布

我不知道是否有可能关闭通信管道时,在不同的线程杀死一个子进程启动。 如果我不叫沟通(),然后杀()将如预期,终止过程中的一个来治五年后。

我发现了一个类似的问题的讨论, 在这里 ,但我没有真正的答案。 我认为我要么必须能够关闭管道或明确地杀子子(这是“睡眠”中的例子),并杀死疏通管道。

我也试图找到答案她这样,但我只发现了这个和这个和这个 ,不直接,据我可以告诉解决这个问题(?)。

所以,我想要做的事情就是能够在第二个线程中运行命令,并得到其所有的输出,但能杀死它立即当我愿意的话。 我可以通过文件和尾巴或类似去,但我觉得应该有一个更好的方式来做到这一点?

import subprocess, time
from threading import Thread

process = None

def executeCommand(command, runCommand):
    Thread(target=runCommand, args=(command,)).start()

def runCommand(command):
    global process
    args = command.strip().split()
    process = subprocess.Popen(args, shell=False, stdout=subprocess.PIPE)

    for line in process.communicate():
        if line:
            print "process:", line,

if __name__ == '__main__':
    executeCommand("./ascript.sh", runCommand)
    time.sleep(1)
    process.kill()

这是脚本:

#!/bin/bash
echo "sleeping five"
sleep 5
echo "slept five"

产量

$ time python poc.py 
process: sleeping five

real    0m5.053s
user    0m0.044s
sys 0m0.000s

Answer 1:

我认为这个问题是process.kill()只杀死直接子过程(庆典)的bash脚本的,而不是子进程。

问题和解决方案描述如下:

  • http://www.doughellmann.com/PyMOTW/subprocess/#process-groups-sessions
  • 如何终止与外壳推出了蟒蛇子=真

使用POPEN(...,preexec_fn = os.setsid)创建进程组os.pgkill杀死整个进程组。 例如

import os
import signal
import subprocess
import time
from threading import Thread

process = None

def executeCommand(command, runCommand):
    Thread(target=runCommand, args=(command,)).start()

def runCommand(command):
    global process
    args = command.strip().split()
    process = subprocess.Popen(
        args, shell=False, stdout=subprocess.PIPE, preexec_fn=os.setsid)

    for line in process.communicate():
        if line:
            print "process:", line,

if __name__ == '__main__':
    executeCommand("./ascript.sh", runCommand)
    time.sleep(1)
    os.killpg(process.pid, signal.SIGKILL)

$ time python poc.py 
process: sleeping five

real    0m1.051s
user    0m0.032s
sys 0m0.020s


Answer 2:

在我看来,要做到这一点,回避了多线程问题最简单的办法是从主线程设置一个杀标志,只是在通信前的脚本运行的线程检查它,杀死脚本时的标志True



Answer 3:

它看起来像你可能是Python的超粗粒度并行的受害者。 更改你的脚本如下:

#!/bin/bash
echo "sleeping five"
sleep 5
echo "sleeping five again"
sleep 5
echo "slept five"

然后输出变为:

process: sleeping five

real    0m5.134s
user    0m0.000s
sys     0m0.010s

如果整个脚本运行的时间将是10秒。 所以它看起来像蟒蛇控制线程实际上不运行,直到bash脚本睡觉之后。 同样,如果你改变你的脚本如下:

#!/bin/bash
echo "sleeping five"
sleep 1
sleep 1
sleep 1
sleep 1
sleep 1
echo "slept five"

然后输出变为:

process: sleeping five

real    0m1.150s
user    0m0.010s
sys     0m0.020s

总之,你的代码工作逻辑上实现。 :)



文章来源: How do I close the stdout-pipe when killing a process started with python subprocess Popen?