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

discord.py长耗时命令运行时其他命令阻塞无法响应问题

问题根因

discord.py 的命令本身基于asyncio异步调度,但你代码中使用的同步subprocess.Popen和配套的process.stdout.readline()属于阻塞式调用,持续读取子进程输出的同步循环会直接霸占事件循环所在的主线程,导致所有协程调度被卡住,其他命令自然无法响应。只要这个读输出的循环不终止,整个机器人的事件处理都会处于阻塞状态。
另外你贴出的代码开头有一行冗余残句stdin=subprocess.PIPE, shell = True),运行前需要删除,否则会触发语法错误。

可行修改方案

两种方案都能避免阻塞主事件循环,实现多命令并行响应:

方案1:使用asyncio原生异步子进程接口

替换同步subprocess模块为asyncio自带的异步子进程实现,所有IO操作都使用异步方法,完全不阻塞事件循环,是最推荐的写法:

import asyncio

@bot.command()
async def start(ctx):
    startCode = 'code'  # 替换为你实际的服务启动命令
    # 创建异步子进程
    process = await asyncio.create_subprocess_shell(
        startCode,
        stderr=asyncio.subprocess.STDOUT,
        stdout=asyncio.subprocess.PIPE,
        stdin=asyncio.subprocess.PIPE
    )
    # 异步逐行读取输出,过程中会主动让出事件循环控制权
    while True:
        line = await process.stdout.readline()
        if not line:
            break
        line = line.decode('utf-8').strip()
        print(line)
        # 若需要将输出同步发送到Discord频道,直接调用await ctx.send(line)即可

方案2:将阻塞逻辑放到独立线程运行

如果不想改动现有子进程相关逻辑,可以用asyncio.to_thread把阻塞的读输出循环放到独立工作线程执行,主事件循环不会被阻塞:

import asyncio
import subprocess

def _read_output_blocking(process):
    # 阻塞逻辑全部放在线程内执行
    for line in iter(process.stdout.readline, b''):
        line = line.decode('utf-8').strip()
        print(line)

@bot.command()
async def start(ctx):
    startCode = 'code'  # 替换为你实际的服务启动命令
    process = subprocess.Popen(
        startCode,
        stderr=subprocess.STDOUT,
        stdout=subprocess.PIPE,
        stdin=subprocess.PIPE,
        shell=True
    )
    # 将阻塞任务提交到线程池执行,不阻塞主协程调度
    await asyncio.to_thread(_read_output_blocking, process)
额外注意
  • 异步代码中禁止直接执行无await的长时间阻塞操作,包括同步文件读写、同步网络请求、同步子进程IO,这类操作都会卡住整个事件循环
  • 如果需要支持多次启动/停止服务,建议把创建的process实例存到全局变量或者类属性中,避免重复启动同一个服务,也方便后续实现停止服务的命令
  • 使用shell=True时存在命令注入风险,不要直接拼接用户传入的不可信内容到启动命令中

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 18:51:06