Python 通过os.system()终止进程中启动的脚本

Python 通过os.system()终止进程中启动的脚本,python,process,os.system,Python,Process,Os.system,我有一个python脚本,它启动了几个进程。每个进程基本上只调用一个shell脚本: from multiprocessing import Process import os import logging def thread_method(n = 4): global logger command = "~/Scripts/run.sh " + str(n) + " >> /var/log/mylog.log" if (debug): logger.de

我有一个python脚本,它启动了几个进程。每个进程基本上只调用一个shell脚本:

from multiprocessing import Process
import os
import logging

def thread_method(n = 4):
    global logger
    command = "~/Scripts/run.sh " + str(n) + " >> /var/log/mylog.log"
    if (debug): logger.debug(command)
    os.system(command)
我启动了其中几个线程,它们是在后台运行的。我希望在这些线程上有一个超时,这样,如果超过超时,它们将被杀死:

t = []
for x in range(10):
    try:
        t.append(Process(target=thread_method, args=(x,) ) )
        t[-1].start()
    except Exception as e:
        logger.error("Error: unable to start thread")
        logger.error("Error message: " + str(e))
logger.info("Waiting up to 60 seconds to allow threads to finish")
t[0].join(60)
for n in range(len(t)):
    if t[n].is_alive():
    logger.info(str(n) + " is still alive after 60 seconds, forcibly terminating")
     t[n].terminate()

问题在于,在进程线程上调用terminate()并不会终止启动的run.sh脚本——它会继续在后台运行,直到我从命令行强制终止它,或者它在内部完成。有没有办法让terminate也杀死os.system()创建的子shell?

改用,因为它的对象对此有明确的定义。

您应该使用事件通知工作进程终止,使用
subprocess
模块运行子进程,然后使用
Popen.terminate()
终止它。调用
Process.terminate()
将不允许it工作者进行清理。请参阅。

在Python 3.3中,子流程模块支持超时:

有关Python 2.x的其他解决方案,请查看此线程:

基于:

导入操作系统
导入时间
从子流程导入Popen
def启动程序(n,标准输出):
#不需要“全局记录器”,您不需要分配给它
command=[os.path.expanduser(“~/Scripts/run.sh”),str(n)]
logger.debug(命令)#不需要if(调试);改为设置日志记录级别
返回Popen(命令,stdout=stdout)#直接运行
#不需要使用线程;Popen是异步的
打开('/tmp/scripts_output.txt')作为文件:
进程=[start_进程(i,文件)对于范围(10)内的i]
#最多等待超时秒,进程才能完成
#您可以使用p.wait()和signal.alarm或threading.Timer
endtime=time.time()+超时
而any(p.poll()对于进程中的p是None)和time.time()

如果可用,请使用
p.wait(timeout)

会混淆subprocess.Popen.terminate和multiprocessing.Process。terminate@J.F.Sebastian但是
multiprocessing.Process.terminate()
不允许它控制的进程清理。我的意思是使用一个事件来终止
多处理
的辅助进程,这样它就可以清理并调用辅助进程控制的子进程上的
subprocess.Popen.terminate()
。你是对的。我只是忽略了问题的这一部分,因为。
import os
import time
from subprocess import Popen

def start_process(n, stdout):
    # no need for `global logger` you don't assign to it
    command = [os.path.expanduser("~/Scripts/run.sh"), str(n)]
    logger.debug(command) # no need for if(debug); set logging level instead
    return Popen(command, stdout=stdout) # run directly

# no need to use threads; Popen is asynchronous 
with open('/tmp/scripts_output.txt') as file:
    processes = [start_process(i, file) for i in range(10)]

    # wait at most timeout seconds for the processes to complete
    # you could use p.wait() and signal.alarm or threading.Timer instead
    endtime = time.time() + timeout
    while any(p.poll() is None for p in processes) and time.time() < endtime:
        time.sleep(.04)

    # terminate unfinished processes
    for p in processes:
        if p.poll() is None:
            p.terminate()
            p.wait() # blocks if `kill pid` is ignored