如何让Disnake机器人与自定义函数实现并发运行?
解决Disnake机器人与计数函数并发执行的问题
问题根源
bot.run(token)是阻塞式调用,会占据主线程,导致后续的counting()永远不会执行;另外你的counting()用了time.sleep(1),即使放到主线程外,同步阻塞的sleep也会干扰机器人的事件循环。
方案1:使用Disnake内置的任务系统(推荐)
Disnake自带的tasks.loop可以创建异步循环任务,和机器人的事件循环无缝兼容,不会产生阻塞。
修正后的完整代码:
import disnake from disnake.ext import commands, tasks import asyncio # 初始化Bot,指定命令前缀 bot = commands.Bot(command_prefix="!") # 消息事件处理,需添加@bot.event装饰器 @bot.event async def on_message(message): # 避免机器人响应自己的消息 if message.author == bot.user: return if message.content == "hello bot": await message.channel.send("hey user") # 必须加上这句,否则命令系统会失效 await bot.process_commands(message) # 初始化计数变量 x = 0 # 创建每秒执行一次的异步任务 @tasks.loop(seconds=1) async def counting(): global x x += 1 print(x) # 用异步sleep替代time.sleep,不会阻塞事件循环 await asyncio.sleep(1) # 机器人启动时启动计数任务 @bot.event async def on_ready(): print(f"已登录为 {bot.user}") counting.start() # 替换成你的机器人token bot.run("你的机器人TOKEN")
方案2:使用线程执行同步计数函数
如果不想修改原有的counting()同步函数,可以把它放到单独的线程中运行,避免阻塞主线程的机器人运行。
代码示例:
import disnake from disnake.ext import commands import time import threading bot = commands.Bot(command_prefix="!") @bot.event async def on_message(message): if message.author == bot.user: return if message.content == "hello bot": await message.channel.send("hey user") await bot.process_commands(message) x = 0 def counting(): global x while True: x += 1 print(x) time.sleep(1) # 启动计数线程,daemon=True确保主线程退出时线程自动终止 threading.Thread(target=counting, daemon=True).start() bot.run("你的机器人TOKEN")
注意事项
- 方案2中如果计数函数需要操作机器人资源(比如发送消息),不要用线程,必须用方案1的异步任务,否则会引发线程安全问题。
内容的提问来源于stack exchange,提问作者AD DAB
相关产品推荐
相关产品推荐

