2012-04-13 4 views
2

Hallo hat, wenn subprocess.Popen mitUnterprozess popen stdout Sperren? ein Problem mit stdout Lesen

[email protected]:~$ python -V 
Python 2.7.3 

heren dem Code: (kommentierten Code ist einige Dinge, die ich versucht habe)

import subprocess 

RUN = './hlds_run -game cstrike -maxplayers 11' 

p = subprocess.Popen(RUN.split(), shell=False, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) 

while 1: 
    try: 
     out = p.stdout.readline() 
     #if out == '': 
     # out = p.stdout.read() 
     #p.stdout.flush() 
    except: 
     p.terminate() 
     break 

    try: 
     err = p.stderr.readline() 
     #if err == '': 
     # err = p.stderr.read() 
     #p.stderr.flush() 
    except: 
     p.terminate() 
     break 
    if out != '': 
     print out.rstrip() 

    if err != '': 
     print err.rstrip() 


    #print '\n' #constantly prints new lines until "Calling BreakpadMiniDumpSystemInit." 

und dies ist der Ausgang im bekommen mit dem Server verbinden und zu trennen:

[email protected]:~/hlds$ python hlds.py 
Auto detecting CPU 
Using breakpad crash handler 
Using Pentium II Optimised binary. 
Setting breakpad minidump AppID = 10 
Auto-restarting the server on crash 
Forcing breakpad minidump interfaces to load 

Looking up breakpad interfaces from steamclient 
Console initialized. 
Calling BreakpadMiniDumpSystemInit 
scandir failed:/home/daniel/hlds/./valve/SAVE 
Installing breakpad exception handler for appid(10)/version(5447) 
scandir failed:/home/daniel/hlds/./platform/SAVE 
Looking up breakpad interfaces from steamclient 
Protocol version 48 
Calling BreakpadMiniDumpSystemInit 

die while-Schleife aufhängt nach:

Calling BreakpadMiniDumpSystemInit. 

aber der Server noch läuft und ich kann verbinden, führen Befehle etc ...


wenn ich laufe:

./hlds_run -game cstrike -maxplayers 11 >> stdout.log 2>&1 

i erhalten die folgende Ausgabe in stdout.log :

[email protected]:~/hlds$ cat stdout.log 
Auto detecting CPU 
Using Pentium II Optimised binary. 
Auto-restarting the server on crash 

Console initialized. 
Using breakpad crash handler 
Setting breakpad minidump AppID = 10 
Forcing breakpad minidump interfaces to load 
Looking up breakpad interfaces from steamclient 
Calling BreakpadMiniDumpSystemInit 
Installing breakpad exception handler for appid(10)/version(5447) 
scandir failed:/home/daniel/hlds/./valve/SAVE 
scandir failed:/home/daniel/hlds/./platform/SAVE 
Protocol version 48 
Exe version 1.1.2.6/Stdio (cstrike) 
Exe build: 14:06:24 Sep 23 2011 (5447) 
STEAM Auth Server 
Server IP address 127.0.1.1:27015 
couldn't exec listip.cfg 
couldn't exec banned.cfg 
Looking up breakpad interfaces from steamclient 
Calling BreakpadMiniDumpSystemInit 
scandir failed:/home/daniel/hlds/./valve/SAVE 
scandir failed:/home/daniel/hlds/./platform/SAVE 

Could not establish connection to Steam servers. 
Reconnected to Steam servers. 
    VAC secure mode is activated. 
ERROR: couldn't open custom.hpk. 
JAMES HETFIELD : hello! 
Dropped JAMES HETFIELD from server 
Reason: Client sent 'drop' 
Sat Apr 14 00:10:54 CEST 2012: Server Quit 

aber wenn ich nicht tun 2> & 1 i noch erhalten diese Ausgabe in stdout und der Rest in stdout.log:

[email protected]:~/hlds$ ./hlds_run -game cstrike -maxplayers 11 >> stdout.log 
Using breakpad crash handler 
Setting breakpad minidump AppID = 10 
Forcing breakpad minidump interfaces to load 
Looking up breakpad interfaces from steamclient 
Calling BreakpadMiniDumpSystemInit 
Installing breakpad exception handler for appid(10)/version(5447) 
Looking up breakpad interfaces from steamclient 
Calling BreakpadMiniDumpSystemInit 

versucht, einen Servermanager und Disponenten als subprocess Lernerfahrung zu schaffen:]

Alle Hilfe dankbar! :)

Antwort

1

Was passiert ist, dass eine der Pipes mit Daten gefüllt wird, so blockiert den Unterprozess, während Ihr Python-Prozess blockiert versucht, eine Zeile aus der anderen Leitung zu lesen, was zu einem Deadlock führt. Wahrscheinlich möchten Sie eine Art von Polling verwenden (select/poll/epoll), anstatt die Reads auf den Pipes zu blockieren.

Ein schneller Hack wäre nicht blockierende Lesevorgänge in Ihrer while-Schleife, aber das führt zu Ihrem Python-Prozess mit viel CPU.

Werfen Sie einen Blick auf die Dokumentation für das select Modul für weitere Informationen zur Lösung des Problems die nicht-hacky Weise.

+0

vielen dank! Gott verdammt, ich liebe diese Seite: D – daniel

+0

Definitiv eine richtige Antwort, da das 'subprocess' Modul intern' 'select' 'verwendet (oder' threading' unter Windows). Das OP könnte jedoch [pexpect] (http://pypi.python.org/pypi/pexpect/) für diese Art von Dingen geeigneter finden. – torek

+0

Das stimmt. Pexpect ist eine bessere Lösung für das Problem, das das OP lösen möchte. Da das OP jedoch versucht hat, das Problem als Lernerfahrung zu lösen, halte ich die Verwendung von Select für anwendbar. – dnaq

0

Konnten Sie dies mit select lösen? Ich finde, dass, wenn ich SRCDS starten, auch nicht blockierend es geht nicht vorbei an der „Calling BreakpadMiniDumpSystemInit“:

p = subprocess.Popen(cmd, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True) 
fcntl.fcntl(p.stdout, fcntl.F_SETFL, fcntl.fcntl(p.stdout, fcntl.F_GETFL) | os.O_NONBLOCK) 
print p.stdout.read() 

Dies druckt auf die „BreakpadMiniDumpSystemInit“ -Nachricht auf, weitere Anrufe Wurf lesen() „Resource temporarily unavailable“ bis etwas auf p.stdin geschrieben wird.

+1

Ja, ich finde es funktioniert ganz gut, ich lernte alles, was ich von diesem Tutorial http://www.doughellmann.com/PyMOTW/select/ wissen musste und änderte es für meine Bedürfnisse.In deinem Fall scheint es, als ob etwas die Stout-Pipe blockiert. – daniel