是否可以从分离的子进程写入输入/读取输出?



我正在尝试通过Python模块管理游戏服务器(供玩家加入的服务器,我没有创建游戏)。但是,我注意到,当 Python 脚本停止请求输入(来自 input())时,服务器会停止。有什么办法吗?

服务器作为子进程运行:server = subprocess.Popen("D:WindowsSystem32cmd.exe", stdin=subprocess.PIPE, stdout=subprocess.PIPE)后跟server.stdin.write调用以运行服务器 exe 文件

如果没有标准输出管道运行,服务器似乎工作正常,但我仍然需要从它接收输出而不停止如果可能的话。 对于这个模糊的问题和我缺乏 python 知识,我深表歉意。

听起来你想做两件事:

  • 服务子进程的标准输出。
  • 等待用户输入input

而且,您需要同时执行这两项操作,并且接近实时 - 当您阻止从子流程读取时,用户无法输入任何命令,当您阻止从用户输入读取时,子流程会挂在停止的管道上。


最简单的方法是为每个线程使用一个线程。

如果没有看到任何代码,很难展示一个好的例子,但像这样:

def service_proc_stdout(proc):
while True:
buf = proc.stdout.read()
do_proc_stuff(buf)
proc = subprocess.Popen(…)
t = threading.Thread(target=service_proc_stdout, args=(proc,))
t.start()
while True:
command = input()
do_command_stuff(command)

听起来你的do_command_stuff正在写信给proc.stdin.这可能只是有效,但如果您将输入推送到其中太快,proc.stdin可能会阻止,从而阻止您读取用户输入。如果您需要解决这个问题,只需启动第三个线程:

def service_proc_stdin(q, proc):
while True:
msg = q.get()
proc.stdin.write(msg)
q = queue.Queue()
tstdin = threading.Thread(target=service_proc_stdin, args=(q, proc))
tstdin.start()

。而现在,你不是直接打电话给proc.stdin.write(…),而是打电话给q.put(…).


线程不是处理并发性的唯一方法。例如,可以使用asyncio事件循环,或围绕非阻塞管道的手动selectors循环。但这可能是最简单的更改,至少如果您不需要在线程之间共享或传递任何内容,除了推送到队列的消息之外。

最新更新