繁体   English   中英

Python:终止subprocess = Success,但它仍在运行(?)

[英]Python: Terminate subprocess = Success, but it's still running (?)

我有一个简单的脚本调用另一个python脚本作为子进程。 我可以确认子进程已启动,我可以获取其PID。

当我尝试终止子进程(在win中)时,我得到针对正确PID的SUCCESS消息,但Windows任务管理器显示第二个python.exe进程仍在运行。

在Win中完成此任务的任何建议? 我将扩展它以最终在OSX和Linux中工作:

简化:

#!/usr/bin/env python

import os, sys
import subprocess
from subprocess import Popen, PIPE, STDOUT, check_call

pyTivoPath="c:\pyTivo\pyTivo.py"

print "\nmyPID: %d" % os.getpid()

## Start pyTivo ##
py_process = subprocess.Popen(pyTivoPath, shell=True, stdout=PIPE, stderr=subprocess.STDOUT)
print "newPID: %s" % py_process.pid

## Terminate pyTivo ##  
#py_process.terminate() - for nonWin (?)
py_kill = subprocess.Popen("TASKKILL /PID "+ str(py_process.pid) + " /f") 

raw_input("\nPress Enter to continue...")

注意:需要Python2.7,psutils不可用

使用TASKKILL命令上的/F (强制)开关。 很多Windows命令没有有用的返回值。 不记得TASKKILL返回是否具有有用的值。


对不起,忽略了你的/F

您可以尝试直接调用win32 api。

import win32api
win32api.TerminateProcess(int(process._handle), -1)

找到了ActiveState页面 记录了一些kill方法,包括上面的Win32方法。

Windows不允许您终止进程的原因也有很多。 常见原因是权限和错误驱动程序具有未正确响应kill信号的挂起I / O请求。

有一些程序,例如ProcessHacker,对杀死进程更加热衷,但我不知道技术细节,虽然我怀疑强制关闭打开文件句柄等,然后调用Terminate。

你可以在Linux上遇到类似的问题,即没有杀死进程的权限,或者进程忽略了kill信号。 但是在Linux上更容易解决,如果kill -9不起作用,它就不能被杀死,这是一种罕见的情况,因为你必须在你的代码中明确地忽略信号9。


0)您可以使用TASKKILL /T来杀死CMD和Python解释器。

1)如果您更改流程创建以直接创建python流程(而不是调用.py并依赖cmd启动),并使用脚本名称作为命令参数,您将获得创建流程时所期望的PID。

2)您可以使用TASKKILL /IM按名称TASKKILL /IM进程,但名称将是python解释器,它可能会杀死意外的进程。

在我的实现中,以下实际上在Windows中创建了两个进程(“cmd.exe”和“python.exe”)。

py_process = subprocess.Popen(pyTivoPath, shell=True, stdout=PIPE, stderr=subprocess.STDOUT)

注意到“python.exe”进程是“cmd.exe”进程的子进程,我将“/ T”(树杀死)开关添加到我的TASKKILL:

py_kill = subprocess.Popen("TASKKILL /PID "+ str(py_process.pid) + " /f /t") 

这导致有效杀死python子进程的期望效果。

创建了两个进程,因为您使用shell=True调用Popen。 看起来你需要使用shell的唯一原因是你使用与解释器的文件关联。 要解决您的问题,您还可以尝试:

from subprocess Popen, PIPE, STDOUT

pyTivoPath = "c:\pyTivo\pyTivo.py"
cmd = r'c:\Python27\python.exe "{}"'.format(pyTivoPath)

# start process
py_process = Popen(cmd, stdout=PIPE, stderr=STDOUT)

# kill process
py_process.terminate()

暂无
暂无

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

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