首页 > 解决方案 > Is it possible to write to input / read output from a detached subprocess?

问题描述

I'm trying to manage a game server (a server for players to join, I didn't create the game) through a Python module. I noticed, however, that the server stops when the Python script stops to ask for input (from input()). Is there any way around this?

The server is ran as a subprocess: server = subprocess.Popen("D:\Windows\System32\cmd.exe", stdin=subprocess.PIPE, stdout=subprocess.PIPE) followed by server.stdin.write calls to run the server exe file

The server seems to work fine if ran without a stdout pipe, but I still need to receive output from it without it stopping if possible. I apologize for the vague question and my lack of python knowledge.

标签: pythonpython-3.7

解决方案


听起来你想做两件事:

  • 服务子进程的标准输出。
  • 等待用户输入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但这可能是最简单的更改,至少如果您不需要在线程之间共享或传递除了推送到队列的消息之外的任何内容。


推荐阅读