You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

subprocess timeout/wait与time.sleep失效问题求助

解决time.sleep()与popen.wait()和Minecraft服务器交互异常问题

核心问题1:stdin缓冲区未刷新,导致命令延迟批量发送

你向Minecraft服务器进程的stdin写入命令时,Python会默认缓冲这些数据,不会立刻传递给服务器。哪怕你加了time.sleep(),之前的命令都堆在缓冲区里,直到后续操作触发缓冲区刷新,才会一次性发送,看起来就像所有命令同时执行了。

解决方案:每次写入后强制刷新缓冲区
还要注意原代码里漏了time模块的导入,必须补上。修正后的代码如下:

import subprocess 
import time
from subprocess import Popen, PIPE

MCser = subprocess.Popen(["java.exe", "-Xms8024M", "-Xmx10096M", "-jar", "quilt-server-launch.jar"], stdout = PIPE, stdin = PIPE, stderr = PIPE)
MCser.stdin.write(b'say test\n')
MCser.stdin.flush()  # 强制刷新缓冲区,立刻发送命令
MCser.stdin.write(b'say Restart after 30s\n')
MCser.stdin.flush()
time.sleep(20)
MCser.stdin.write(b'say Restart after 10s\n')
MCser.stdin.flush()
time.sleep(10)
MCser.stdin.write(b'stop\n')
MCser.stdin.flush()

核心问题2:Popen.wait()用法完全错误

Popen.wait(timeout)的作用是等待进程终止,超时后抛出异常。但Minecraft服务器启动后会持续运行,不会自动终止,所以第一次wait(30)超时后执行写入,后续的wait(20)还是在等同一个运行中的进程,会立刻超时触发写入,导致所有命令瞬间执行。

正确做法:用time.sleep()控制时间间隔,配合缓冲区刷新
不需要用wait()来实现计时逻辑,直接用time.sleep()即可,这也是最直观的方式。

可选优化:使用文本模式简化操作

如果觉得字节流操作麻烦,可以开启文本模式(Python 3.7+用text=True,旧版本用universal_newlines=True),这样可以直接写入字符串,不用转成字节:

import subprocess 
import time
from subprocess import Popen, PIPE

MCser = subprocess.Popen(["java.exe", "-Xms8024M", "-Xmx10096M", "-jar", "quilt-server-launch.jar"], 
                        stdout = PIPE, stdin = PIPE, stderr = PIPE, text=True)
MCser.stdin.write('say test\n')
MCser.stdin.flush()
MCser.stdin.write('say Restart after 30s\n')
MCser.stdin.flush()
time.sleep(20)
MCser.stdin.write('say Restart after 10s\n')
MCser.stdin.flush()
time.sleep(10)
MCser.stdin.write('stop\n')
MCser.stdin.flush()

内容的提问来源于stack exchange,提问作者Meowts

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 00:47:39