gpt4 book ai didi

python - 在单独的线程中执行 run_coroutine_threadsafe

转载 作者:行者123 更新时间:2023-12-02 16:26:33 35 4
gpt4 key购买 nike

我有一个永远运行的脚本(它检查文件中的更改)。每当生成奇怪的文件时,我都需要发送 Discord 消息。

  • 问题是,事件监视函数(下面的 def run(self):)来自子类,所以我不能将它更改为 async def run(self):。因此我不能使用 await channel.send()
  • 我对此的解决方案是使用 run_coroutine_threadsafe,如下所述:https://stackoverflow.com/a/53726266/9283107 .效果很好!但问题是,消息被放入队列中,并且在该脚本完成之前它们永远不会被发送(在我的情况下是:从不)。我假设发送消息函数被放入此脚本所在的线程中,因此该线程永远不会到达它们?

也许我们可以将 run_coroutine_threadsafe 放到一个单独的线程中之类的?这是我能做的最小的例子,它仍然显示我的子类问题。

import discord
import os
import asyncio
import time

# CHANNEL_ID = 7659170174????????
client = discord.Client()
channel = None

class Example():
# Imagine this run comes from a subclass, so you can't add sync to it!
def run(self):
# await channel.send('Test') # We can't do this because of the above comment
asyncio.run_coroutine_threadsafe(channel.send('Test'), _loop)
print('Message sent')

@client.event
async def on_ready():
print('Discord ready')
global channel
channel = client.get_channel(CHANNEL_ID)

for i in range(2):
Example().run()
time.sleep(3)

print('Discord messages should appear by now. Sleeping for 20s to give it time (technically this would be infinite)')
time.sleep(20)
print('Script done. Now they only get sent for some reason')

_loop = asyncio.get_event_loop()

client.run('Your secret token')

最佳答案

首先,请注意您不能从 async def 调用阻塞代码,例如 time.sleep()。要启动阻塞函数并让它与 asyncio 通信,您可以从 on_ready 甚至从顶层生成一个后台线程,如下所示:

# checker_function is the function that blocks and that
# will invoke Example.run() in a loop.
threading.Thread(
target=checker_function,
args=(asyncio.get_event_loop(), channel)
).start()

您的主线程将运行 asyncio 事件循环,您的后台线程将检查文件,使用 asyncio.run_coroutine_threadsafe() 与 asyncio 和 discord 通信。

正如您链接到的答案下的评论中指出的那样,asyncio.run_coroutine_threadsafe 假定您有多个线程在运行(因此“线程安全”),其中一个运行事件循环。在您实现它之前,任何使用 asyncio.run_coroutine_threadsafe 的尝试都将失败。

关于python - 在单独的线程中执行 run_coroutine_threadsafe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64368729/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com