我不知道是否有可能关闭通信管道时,在不同的线程杀死一个子进程启动。 如果我不叫沟通(),然后杀()将如预期,终止过程中的一个来治五年后。
我发现了一个类似的问题的讨论, 在这里 ,但我没有真正的答案。 我认为我要么必须能够关闭管道或明确地杀子子(这是“睡眠”中的例子),并杀死疏通管道。
我也试图找到答案她这样,但我只发现了这个和这个和这个 ,不直接,据我可以告诉解决这个问题(?)。
所以,我想要做的事情就是能够在第二个线程中运行命令,并得到其所有的输出,但能杀死它立即当我愿意的话。 我可以通过文件和尾巴或类似去,但我觉得应该有一个更好的方式来做到这一点?
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
我认为这个问题是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
在我看来,要做到这一点,回避了多线程问题最简单的办法是从主线程设置一个杀标志,只是在通信前的脚本运行的线程检查它,杀死脚本时的标志True
。
它看起来像你可能是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?