Как принудительно приостановить процесс, который порождает подпроцессы - PullRequest
0 голосов
/ 08 декабря 2018

Мне нужно запустить процессы (программы, скрипты bash и т. Д.), Которые могут порождать другие процессы, но мне также нужно применить тайм-аут в случае, если что-то зависнет, и я хочу, чтобы выполнение программы продолжалось после истечения тайм-аута.Я использую следующую функцию run ():

import subprocess, shlex, threading
from threading import Timer

def run(cmd, timeout_sec=5):
    def kill_proc(proc, timedout):
        timedout['value'] = True
        proc.kill()

    try:
        proc = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE)

        timedout = {'value': False}
        timer = threading.Timer(timeout_sec, kill_proc, [proc, timedout])
        timer.start()
        stdout, stderr = proc.communicate()
        timer.cancel()

        return stdout.decode('utf-8'), stderr.decode('utf-8'), proc.returncode, timedout['value']
    except Exception as e:
        print('Could not execute: %s - with error: %s' % (cmd, e))
        return '', '', 1, False

По большей части это работает, и оно способно грациозно прервать тайм-аут вызова, например:

run(cmd='sleep 1m', timeout_sec=2)

Где это кажетсяповесить трубку, скажем, у меня есть следующий bash-скрипт с именем sleeper.sh:

#!/bin/bash
sleep 1m

, и если я введу следующую команду:

run(cmd='sleeper.sh', timeout_sec=2)

, он будет сидеть там и ждать1 минута до завершения команды.Есть ли способ, чтобы я переписал свою функцию run () для принудительного тайм-аута процесса независимо от того, какие дочерние процессы создаются?

1 Ответ

0 голосов
/ 08 декабря 2018

Вот пример кода о том, как этого добиться в bash.Возможно, вы сможете применить его к своей программе:

$ date; timeout 1 sleep 5 ; date
Sat Dec  8 18:02:44 UTC 2018
Sat Dec  8 18:02:45 UTC 2018

Короче говоря, посмотрите, работает ли предварительная «длительность тайм-аута» к началу ваших команд.

...