subprocess timeout

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
glaslos
User
Beiträge: 23
Registriert: Donnerstag 12. Februar 2009, 18:55
Kontaktdaten:

Hallo, ich würde gerne folgenden Code durch subprocess ersetzen:

Code: Alles auswählen

f = os.fork()

    if f < 0:
        print 'error launching!'
        usage()
    elif f > 0:
        # parent
        print 'launching child script, PID is %s' % f
        print 'sleeping for %d seconds ...' % secs
        time.sleep(secs)
        print 'Killing processes ...'
        os.system("kill `ps ax | grep scrips.php | awk '{print $1}'`")
    elif f == 0:
        # child
        start = time.time()
        o, i, e = popen2.popen3('php scrips.php %s' % prog)
        err = e.read()
        out = o.read()
        i.close()
        e.close()
        o.close()
        end = time.time()
        print err
        analysis = distill(prog, start, end, err)
        sys.exit(0)
Ich gehe davon aus, dass das php script nicht fertig läuft und ich lese erfolgreich das resultat aus err aus.

Hier mein Ansatz:

Code: Alles auswählen

def sub_test(prog, secs):
    proc = subprocess.Popen(['php', 'script.php', prog],
                                shell = False,
                                stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE,
                                )
    print 'PARENT : Pausing before sending signal...'
    sys.stdout.flush()

    signal.signal(signal.SIGALRM, alarm_handler)
    signal.alarm(secs)
    stdout_value = ""
    stderr_value = ""
    try:
        stdout_value, stderr_value = proc.communicate()
        signal.alarm(0)
    except Alarm:
        print "Oops, taking too long!"
    finally:
        print "out", repr(stdout_value)
        print "err", repr(stderr_value)
    print 'PARENT : Signaling child'
    sys.stdout.flush()
    os.kill(proc.pid, signal.SIGKILL)
    sys.exit(0)
Läuft prima, aber wenn das Timeout erreicht wird, bricht das script ab aber stderr_out ist leer. Tipps?
deets

Naja, das ist ja auch kein Wunder. Du unterbrichst ja den communicate()-Aufruf recht unsanft mit einem Alarm - wie soll der gute denn dann noch eine Zuweisung machen?

Das hier geht (threading statt Alarm, weil wegen simpler fuer mich - alarm sollte aber auch gehen):

Code: Alles auswählen

import subprocess
import threading
import time
from functools import partial

def killer(proc):
    time.sleep(3)
    print "killing in the name of..."
    proc.kill()

    
def sub_test():
    proc = subprocess.Popen(['python', '/tmp/stderrwriter.py'],
                                shell = False,
                                stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE,
                                )
    print 'PARENT : Pausing before sending signal...'

    #signal.signal(signal.SIGALRM, alarm_handler)
    #signal.alarm(secs)
    threading.Thread(target=partial(killer, proc)).start()
    stdout_value, stderr_value = proc.communicate()
    print "out", repr(stdout_value)
    print "err", repr(stderr_value)


sub_test()
Antworten