Python 在Windows上终止子过程(subprocess)

windows subprocess 终止进程

Python 2 subprocess.Popen Windows终止进程

import subprocess
# Launch process
cmd_list = ["notepad.exe"]
process = subprocess.Popen(
               cmd_list,
               stdin=subprocess.PIPE,
               stdout=subprocess.PIPE,
               stderr=subprocess.PIPE,
               shell=True)
# Terminate
Process.terminate() or Process.kill()

你会发现 Process 停止了,但记事本没有被成功的 kill 掉,因为shell=True 的关系。

解决方案1:psutil

import psutil
import subprocess
from threading import Timer
# You need to pip install psutil package
def kill(proc_pid):
    parent_proc = psutil.Process(proc_pid)
    for child_proc in parent_proc.children(recursive=True):
        child_proc.kill()
    parent_proc.kill()
# Launch process
cmd_list = ["notepad.exe"]
proc_obj = subprocess.Popen(
               cmd_list,
               stdin=subprocess.PIPE,
               stdout=subprocess.PIPE,
               stderr=subprocess.PIPE,
               shell=True)
# set process 300 sec timeout
proc_timeout = 300
proc_timer = Timer(proc_timeout, kill, [proc_obj.pid])
try:
    proc_timer.start()  # start timer
    rt_code = proc_exec.wait() 
    # python 2 not supported proc_exec.wait(timeout=300)
finally:
    proc_timer.cancel()

解决方法2:Windows command

import psutil
import subprocess
from threading import Timer
# You need to pip install psutil package
def kill(proc_pid):
    # kill process with subprocess
    kill_proc = subprocess.Popen(
        "TASKKILL /F /PID {pid} /T".format(pid=proc_pid),
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE)
# Launch process
cmd_list = ["notepad.exe"]
proc_obj = subprocess.Popen(
               cmd_list,
               stdin=subprocess.PIPE,
               stdout=subprocess.PIPE,
               stderr=subprocess.PIPE,
               shell=True)
# set process 300 sec timeout
proc_timeout = 300
proc_timer = Timer(proc_timeout, kill, [proc_obj.pid])
try:
    # start timer
    proc_timer.start()
    # python 2 not supported proc_exec.wait(timeout=300)
    rt_code = proc_exec.wait() 
finally:
    proc_timer.cancel()


解决问题

参考文章

附录:

你可以使用此句柄终止使用ctypes或pywin32扩展名的子进程。

# Create a process that won't end on its own
import subprocess
process = subprocess.Popen(['python.exe', '-c', 'while 1: pass'])


# Kill the process using pywin32
import win32api
win32api.TerminateProcess(int(process._handle), -1)


# Kill the process using ctypes
import ctypes
ctypes.windll.kernel32.TerminateProcess(int(process._handle), -1)


# Kill the proces using pywin32 and pid
import win32api
PROCESS_TERMINATE = 1
handle = win32api.OpenProcess(PROCESS_TERMINATE, False, process.pid)
win32api.TerminateProcess(handle, -1)
win32api.CloseHandle(handle)


# Kill the proces using ctypes and pid
import ctypes
PROCESS_TERMINATE = 1
handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, False, process.pid)
ctypes.windll.kernel32.TerminateProcess(handle, -1)
ctypes.windll.kernel32.CloseHandle(handle)

您可以使用pywin32或ctypes来调用Windows TerminateProcess API。
只需选择一个-两者都不需要。
如果您不喜欢访问Popen返回的对象的未记录的_handle成员,则可以使用已记录的pid成员和Windows OpenProcess API来获得相同的结果。

参考原文地址

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WMSmile

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值