【问题标题】:Is it possible to write to input / read output from a detached subprocess?是否可以从分离的子进程写入输入/读取输出?
【发布时间】:2018-07-22 04:09:34
【问题描述】:

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

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

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

【问题讨论】:

  • 通常,您不希望服务器调用input()。它应该从客户那里获得输入。如果您确实需要从运行服务器的用户那里获取输入,您可能希望将所有服务器内容移至后台线程,或者将sys.stdin 置于非阻塞模式,这样您可以将其放入相同的 selectorsasyncio 或您用于服务器的任何循环中。 (甚至连你如何实现服务器的最模糊概念都没有,很难说比这更具体的了。)
  • 我应该更清楚。我没有创建游戏。我正在为 Steam 游戏启动专用服务器,我想尝试让 Discord 服务器中的用户通过 discord 命令将输入​​发送到服务器的标准输入。我的问题是当 python 脚本运行时游戏服务器停止(等待输入)。

标签: python python-3.7


【解决方案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(…)


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

【讨论】:

  • 感谢您的回答!它按预期工作。对于不清楚的问题再次抱歉!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多