无法在Windows上使用Python杀死正在运行的子进程

时间:2015-07-27 23:41:54

标签: python python-2.7 subprocess kill taskkill

我有一个Python脚本,每60秒运行一整天的检查时间,因此它可以在一天中的特定时段开始/结束任务(其他python脚本)。

这个脚本几乎都运行正常。任务在正确的时间开始,并在新的cmd窗口上打开,因此主脚本可以继续运行并对时间进行采样。唯一的问题是它不会杀死任务。

import os
import time
import signal
import subprocess
import ctypes


freq = 60 # sampling frequency in seconds

while True:    
    print 'Sampling time...'
    now = int(time.time())

    #initialize the task.. lets say 8:30am
    if ( time.strftime("%H:%M", time.localtime(now)) == '08:30'):
        # The following method is used so python opens another cmd window and keeps original script running and sampling time 
        pro = subprocess.Popen(["start", "cmd", "/k", "python python-task.py"], shell=True)

    # kill process attempts.. lets say 11:40am
    if ( time.strftime("%H:%M", time.localtime(now)) == '11:40'):
        pro.kill()    #not working - nothing happens

        pro.terminate()    #not working - nothing happens

        os.kill(pro.pid, signal.SIGINT) #not working - windows error 5 access denied

        # Kill the process using ctypes - not working - nothing happens
        ctypes.windll.kernel32.TerminateProcess(int(pro._handle), -1)

        # Kill process using windows taskkill - nothing happens
        os.popen('TASKKILL /PID '+str(pro.pid)+' /F')

    time.sleep(freq)

重要提示:任务脚本python-task.py将无限期运行。这正是为什么我需要在它仍在运行的某个时间“强制”杀死它的原因。

任何线索?我究竟做错了什么?如何杀死它?

1 个答案:

答案 0 :(得分:1)

您正在杀死产生子流程的shell,而不是您的子流程。

编辑:来自文档:

您需要在Windows上指定shell = True的唯一时间是您希望执行的命令是否内置到shell中(例如dir或copy)。您不需要shell = True来运行批处理文件或基于控制台的可执行文件。

警告

如果与不受信任的输入结合使用,则传递shell = True可能会造成安全隐患。有关详细信息,请参阅“常用参数”下的警告。

因此,不是传递单个字符串,而是在列表中单独传递每个参数,并使用shell避开。您可能希望为子项使用与父项相同的可执行文件,因此它通常类似于:

pro = subprocess.Popen([sys.executable, "python-task.py"])