python - 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.
解决方案
听起来你想做两件事:
- 服务子进程的标准输出。
- 等待用户输入
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
但这可能是最简单的更改,至少如果您不需要在线程之间共享或传递除了推送到队列的消息之外的任何内容。
推荐阅读
- amazon-web-services - AWS - Lambda 授权方返回错误 500
- sprite - Add sprite in function in Phaser 3
- google-apps-script - Google App Maker 在从数据模型获取页面名称时导航到页面
- python - 当我执行 Python dot py 文件时,它什么也没显示
- wpf - 带样式的动画矩形:在样式外指定 DoubleAnimation 的一个属性
- java - Spring Boot 应用程序在环境中引发错误:org.springframework.core.serializer.support.SerializationFailedException
- typescript - 在 stencilJS 项目中设置 tsconfig baseURL 不起作用
- mysql - 显示具有匹配条件的最新 ID
- c++ - gdb 输出启动线程但给出输出
- c# - 自动选中下拉列表中的复选框