使用subprocess.Popen
时,stdout读取有问题daniel@desktop:~$ python -V
Python 2.7.3
继承人代码:(评论代码是我尝试过的一些东西)
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."
这是连接到服务器并断开连接时的输出:
daniel@desktop:~/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
while循环在之后锁定:
Calling BreakpadMiniDumpSystemInit.
但服务器仍在运行,我可以连接,运行命令等......
如果我跑:
./hlds_run -game cstrike -maxplayers 11 >> stdout.log 2>&1
我在stdout.log中得到以下输出:
daniel@desktop:~/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
但是,如果我不做2>& 1我仍然在stdout中获得此输出,其余的在stdout.log中:
daniel@desktop:~/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
尝试创建servermanager和dispatcher作为子流程学习体验:]
所有帮助表示赞赏! :)
答案 0 :(得分:1)
发生的事情是其中一个管道被数据填满,从而在你的python进程被阻塞时阻塞了子进程,试图从另一个管道读取一行,导致死锁。您可能希望使用某种轮询(select / poll / epoll)而不是对管道进行阻塞读取。
快速入侵是在你的while循环中进行非阻塞读取,但这会导致你的python进程使用大量的CPU。
请查看select模块的文档,了解有关以非黑客方式解决问题的更多信息。
答案 1 :(得分:0)
您是否能够使用select解决此问题?我发现当我启动SRCDS甚至非阻塞时,它不会超过“调用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()
这打印到“BreakpadMiniDumpSystemInit”消息,进一步调用read()抛出“资源暂时不可用”,直到写入p.stdin。