python - 在两个线程之间创建一个钩子
问题描述
我目前在我的 discord.py 机器人和另一个线程之间遇到问题,我需要创建一个钩子来从一个类中调用一个函数,比如一个 webhook,但在两个线程之间,我的代码的一个简单版本:
import serial
import threading
class bot: # this class is constantly running other functions, can't get halted by 'usb.readline()' or the connection to the server will be closed
async def on_button_pressed(self, button_pressed): # the goal is to make this function run every time the side_thread detects a button press
if button_pressed == 0:
await channel.connect() # if button 0 is pressed, bot connects to a voice channel
elif button_pressed == 1:
await voice.disconnect() # if button 1 is pressed, bot disconnects from voice channel
def side_thread(): # reads the information an microcontroller send to pc
usb = serial.Serial('com4', baudrate=115200)
while True:
uncoded_data = usb.readline() # program waits a response from usb here
data_str = str(uncoded_data[0:len(uncoded_data)].decode('utf-8'))
button_pressed = int(data_str[:1]) # button_pressed can be 0, 1, 2, 3 or 4 depending on what button was pressed
print(f'button {button_pressed} was pressed')
# the problem is here, idk how to create a hook to call on_button_pressed and pass the arguments since it is in another thread,
# already tried putting asyncio.run(bot.on_button_pressed(button_pressed)) here but it doesn't work since it isn't the main thread running the function
t1 = threading.Thread(target=side_thread)
t1.start()
bot = bot()
我试图将 on_button_pressed 函数放在 side_thread 中,但机器人无法连接,可能是因为异步函数不是线程安全的。
我的目标是,每当我按下按钮时,它都会自动将 on_button_pressed 函数作为主线程运行,而无需停止它,也无需不断检查变量(也停止代码或使按钮极度延迟)
为了尝试更好地解释一下,模拟按钮按下,您可以用 side_thread 替换:
import random
import time
def side_thread(): # reads the information an microcontroller send to pc
while True:
button_pressed = random.randint(0, 4)
time.sleep(5) # simulates a random button press every 5 seconds
print(f'button {button_pressed} was pressed')
而且我希望每次按下按钮时都会将 bot.on_button_pressed 作为主线程运行。要检查这一点,您可以在 async func 上打印线程的名称,它应该与init方法中的相同:
class bot: # can't get halted by a while loop or a lock
def __init__(self):
print(threading.current_thread().name) # prints 'MainThread'
async def on_button_pressed(self, button_pressed): # goal is to make this function run every time the side_thread detects a button press
print(threading.current_thread().name) # it should also print the same as the __init__, if it prints differently it isn't working
例如,如果我添加asyncio.run(bot.on_button_pressed(button_pressed))
到 side_thread 的末尾,则 bot 类上的两个打印将不同,因此它将不起作用
解决方案
推荐阅读
- pytorch - 训练 opennmt 时出错 - 找不到 caffe2_detectron_ops.dll
- python - 将数据框列与列表中的一个因子相乘,该因子是基于另一列选择的
- python - 使用 AutoDesk API 时出现 401(未经授权)错误
- java - 为什么在junit断言中具有相同字段的两个Spark数据帧模式不相等?
- mysql - 如何获得新的。在 MySQL 触发器/插入后动态值?
- cassandra - Cassandra cqlsh 连接和通过复制命令插入数据?
- ember.js - 在 MacOS 上安装 Ember.js
- android - 当应用程序进入后台时片段销毁
- r - R中多个文本文件的可读性分数
- javascript - 一键启动确认框后需要禁用是/否