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

时间:2018-07-22 04:09:34

标签: python python-3.7

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

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

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

1 个答案:

答案 0 :(得分:1)

听起来您想做两件事:

  • 服务子流程的标准输出。
  • 等待用户在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(…)


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