如何用Python multiprocessing实现Discord触发的Deadman Switch功能
问题解决方案
现有代码错误点
- 跨进程共享变量操作错误:
multiprocessing.Manager创建的布尔类型对象必须通过.value属性读写,直接赋值sign = xxx会覆盖变量本身的指向,无法实现跨进程状态同步 - Discord消息回调事件
on_message缺少@client.event装饰器,收到消息时不会触发对应逻辑 discord.Client实例无法跨进程序列化传递,必须在Discord监听子进程内部初始化- 缺少
freeze_support方法导入,Windows环境下运行会直接抛出异常 - 消息匹配规则不符合需求:原代码判断消息内容完全等于「911」,需求是匹配包含「911」的所有消息
- 计时器进程读取共享变量时未访问
.value属性,永远无法接收到停止信号
修正后可运行代码
from time import sleep import discord import multiprocessing from multiprocessing import freeze_support def Timer(sign): for second in range(15): # 读取共享变量的value属性获取实时值 if sign.value: print("bloooock") # 此处可填写你需要调用的指定函数逻辑 break print("passsssss") sleep(1) def discord_message(sign): # 客户端在子进程内部初始化,v2.x版本需要显式声明Intents intents = discord.Intents.default() intents.message_content = True client = discord.Client(intents=intents) @client.event async def on_ready(): print('Logged on as', client.user) # 补上事件装饰器 @client.event async def on_message(message): # 忽略机器人自己发的消息避免循环触发 if message.author == client.user: return messageContent = message.content # 匹配包含911的消息 if "911" in messageContent: # 修改共享变量的value属性实现跨进程同步 sign.value = True # 如果需要直接销毁整个脚本,放开下面两行注释即可 # import os # os.kill(os.getppid(), 9) # 这里替换为你自己的机器人Token client.run('你的Discord机器人Token') if __name__ == '__main__': freeze_support() manager = multiprocessing.Manager() sign = manager.Boolean(False) p1 = multiprocessing.Process(target=Timer, args=(sign,)) p2 = multiprocessing.Process(target=discord_message, args=(sign,)) p1.start() p2.start() p1.join() # 计时器停止后如果需要直接结束Discord监听进程,保留下面两行 p2.terminate() p2.join()
注意事项
使用discord.py v2.0及以上版本时,需要先在Discord开发者后台开启对应机器人的「Message Content Intent」权限,否则无法读取消息内容。
内容的提问来源于stack exchange,提问作者Joseph Yosoevsky
相关产品推荐
相关产品推荐

