是否可以从分离的子进程写入输入/读取输出?
Is it possible to write to input / read output from a detached subprocess?
我正在尝试通过 Python 模块管理游戏服务器(供玩家加入的服务器,我没有创建游戏)。但是,我注意到,当 Python 脚本停止请求输入(来自 input())时,服务器会停止。有什么解决办法吗?
服务器 运行 作为子进程:
server = subprocess.Popen("D:\Windows\System32\cmd.exe", stdin=subprocess.PIPE, stdout=subprocess.PIPE)
随后 server.stdin.write
调用 运行 服务器 exe 文件
如果 运行 没有 stdout 管道,服务器似乎工作正常,但我仍然需要从它接收输出,如果可能的话,它不会停止。
对于含糊不清的问题和我缺乏 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
循环。但这可能是最简单的更改,至少如果您不需要在线程之间共享或传递除推送到队列的消息之外的任何内容。
我正在尝试通过 Python 模块管理游戏服务器(供玩家加入的服务器,我没有创建游戏)。但是,我注意到,当 Python 脚本停止请求输入(来自 input())时,服务器会停止。有什么解决办法吗?
服务器 运行 作为子进程:
server = subprocess.Popen("D:\Windows\System32\cmd.exe", stdin=subprocess.PIPE, stdout=subprocess.PIPE)
随后 server.stdin.write
调用 运行 服务器 exe 文件
如果 运行 没有 stdout 管道,服务器似乎工作正常,但我仍然需要从它接收输出,如果可能的话,它不会停止。 对于含糊不清的问题和我缺乏 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
循环。但这可能是最简单的更改,至少如果您不需要在线程之间共享或传递除推送到队列的消息之外的任何内容。