5

いくつかのプロセスを起動するPythonスクリプトがあります。各プロセスは基本的にシェルスクリプトを呼び出すだけです。

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スクリプトが強制終了されないことです。コマンドラインから強制的に強制終了するか、内部で終了するまで、バックグラウンドで実行を続けます。os.system()によって作成されたサブシェルも終了させる方法はありますか?

4

4 に答える 4

4

イベントを使用してワーカーに終了を通知し、subprocessモジュールでサブプロセスを実行してから、 で終了する必要がありPopen.terminate()ます。呼び出しProcess.terminate()ても、ワーカーはクリーンアップできません。のドキュメントをProcess.terminate()参照してください。

于 2012-09-07T16:29:38.550 に答える
2

subprocess代わりに、オブジェクトが明示的にこれを行うterminate()メソッドを持っているものを使用してください。

于 2012-09-07T15:36:56.407 に答える
2

Python 3.3 では、subprocess モジュールがタイムアウトをサポートしています: http://docs.python.org/dev/library/subprocess.html

Python 2.x に関するその他のソリューションについては、このスレッドを参照してください: Using module 'subprocess' with timeout

于 2012-09-07T16:34:24.907 に答える
1

ハングせずにPythonでプロセス出力の読み取りを停止することに基づいていますか? :

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

利用p.wait(timeout)可能な場合に使用します。

于 2012-09-07T16:57:23.827 に答える