簡體   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