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()
请问代码为何失效?是否可以禁用消息发送频率限制?
问题解答
代码失效原因
线程冗余+事件循环缺失
你的bot类已经继承了threading.Thread,本身就是线程类,没必要再额外套一层Thread去调用run()方法。更关键的是:discord.py的运行依赖asyncio事件循环,但Python默认只在主线程创建事件循环,子线程没有默认的事件循环,直接调用client.run()就会触发你看到的错误。逻辑漏洞
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
相关产品推荐
相关产品推荐

