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

discord.py多机器人线程运行报错:无当前事件循环问题排查

问题描述

我想写Python脚本同时运行多个Discord机器人,用来绕过消息发送频率限制,但运行时出现以下错误:

RuntimeError: There is no current event loop in thread 'Thread-10'

我的代码如下:

import discord
import threading
from discord.ext import commands

class bot(threading.Thread):
    def __init__(self, token):
        threading.Thread.__init__(self)
        self.token = token


    def run(self):
        client = commands.Bot(command_prefix='*')
        
        @client.event
        async def on_ready():
            x = []
            for i in client.get_all_channels():
                if i.name.isnumeric():
                    x.append(i)

            await i.send('Message')

        client.run(self.token)


bot1 = bot('ExampelToken1')
bot2 = bot('ExampelToken2')
bot3 = bot('ExampelToken3')
bot4 = bot('ExampelToken4')
bot5 = bot('ExampelToken5')
th1 = threading.Thread(target=bot1.run,args=())
th2 = threading.Thread(target=bot2.run,args=())
th3 = threading.Thread(target=bot3.run,args=())
th4 = threading.Thread(target=bot4.run,args=())
th5 = threading.Thread(target=bot5.run,args=())
th1.start()
th2.start()
th3.start()
th4.start()
th5.start()

请问代码为何失效?是否可以禁用消息发送频率限制?


问题解答

代码失效原因

  1. 线程冗余+事件循环缺失
    你的bot类已经继承了threading.Thread,本身就是线程类,没必要再额外套一层Thread去调用run()方法。更关键的是:discord.py的运行依赖asyncio事件循环,但Python默认只在主线程创建事件循环,子线程没有默认的事件循环,直接调用client.run()就会触发你看到的错误。

  2. 逻辑漏洞
    on_ready函数里最后执行await i.send('Message'),这里的i是循环的最后一个元素,如果没有匹配到数字名称的频道,i会处于未定义状态,直接报错。正确的做法应该遍历收集到的x列表里的频道发送消息。

修复后的代码示例

import discord
import threading
import asyncio
from discord.ext import commands

class BotThread(threading.Thread):
    def __init__(self, token):
        super().__init__()
        self.token = token

    def run(self):
        # 子线程手动创建并绑定事件循环
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        
        # 必须指定intents,否则无法获取频道等资源
        client = commands.Bot(command_prefix='*', intents=discord.Intents.all())
        
        @client.event
        async def on_ready():
            print(f"Bot {client.user} 已上线")
            target_channels = []
            for channel in client.get_all_channels():
                # 只筛选文本频道且名称为数字的
                if channel.name.isnumeric() and isinstance(channel, discord.TextChannel):
                    target_channels.append(channel)
            
            # 遍历目标频道发送消息
            for channel in target_channels:
                try:
                    await channel.send('Message')
                    print(f"已发送消息到频道 {channel.name}")
                except Exception as e:
                    print(f"发送失败: {e}")

        # 在当前子线程的事件循环中启动bot
        loop.run_until_complete(client.start(self.token))

# 初始化并启动所有bot线程
bots = [
    BotThread('ExampelToken1'),
    BotThread('ExampelToken2'),
    BotThread('ExampelToken3'),
    BotThread('ExampelToken4'),
    BotThread('ExampelToken5')
]

for bot in bots:
    bot.start()

# 等待所有线程执行完毕
for bot in bots:
    bot.join()

关于消息发送频率限制

Discord的消息发送频率限制是服务器端强制规则,无法通过客户端设置禁用。官方设置这个限制是为了防范垃圾消息和API滥用,如果你试图通过批量账号绕过限制,一旦被检测到,账号会被封禁,严重情况下关联IP也会被限制。

如果确实有批量发送需求,建议:

  • 严格遵守Discord的API频率限制
  • 用多个账号分摊发送量,但要确保每个账号的行为符合服务条款
  • 加入合理的延迟机制,避免触发限制

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 01:20:37