【问题标题】:How to use asyncio with threading in Python如何在 Python 中使用 asyncio 和线程
【发布时间】:2020-10-22 00:04:19
【问题描述】:

我正在尝试将 asyncio 与线程一起用于 Discord Bot。我找到了 this 脚本,我根据自己的需要进行了更改:

import time
import threading as th
import asyncio
import discord

class discordvars(object):
    client=discord.Client()
    TOKEN=('---')
    running_discordthread=False

    discordloop = asyncio.get_event_loop()
    discordloop.create_task(client.start(TOKEN))
    discordthread=th.Thread(target=discordloop.run_forever)

def start():
    if discordvars.running_discordthread==False:
        discordvars.discordthread.start()
        print("Discord-Client started...")
        discordvars.running_discordthread=True
    else:
        print("Discord-CLient allready running...")
    time.sleep(2)
    
def stop():
    if discordvars.running_discordthread==True:
        discordvars.discordloop.call_soon_threadsafe(discordvars.discordloop.stop())
        print("Requestet Discord-Client stop!")
        discordvars.discordthread.join()
        print(discordvars.discordthread.isAlive())
        time.sleep(1)
        print("Discord-Client stopped...")
        discordvars.running_discordthread=False
    else:
        print("Discord-Client not running...")
    time.sleep(2)


@discordvars.client.event
async def on_message(message):
    if message.content.startswith('!test'):
        embed = discord.Embed(title="test", color=0x0071ce, description="test")
        await message.channel.send(embed=embed)

使用 start() 函数启动脚本效果很好。使用 stop() 函数停止也可以以某种方式工作。如果我调用 stop() 函数,它会打印:“False”,所以我认为线程已停止。但是如果我再调用 start() 函数,我会得到一个错误:

RuntimeError: 线程只能启动一次

这个脚本是一个大项目的一部分,所以我从另一个脚本调用函数。但我认为这不应该是问题。

有什么问题?提前致谢。

【问题讨论】:

    标签: python python-asyncio python-multithreading


    【解决方案1】:

    您无法重新启动现有线程,但您可以启动一个运行事件循环的新线程。您可以通过将分配到 discordthreadstart 函数来实现。

    而您对call_soon_threadsafe 的调用是错误的。您需要将discordloop.stop 传递给它,不带括号。那是指实际的函数,而不是立即调用它,并允许循环线程调用它,这是本意:

    discordloop.call_soon_threadsafe(discordloop.stop)
    

    最后,您的 init 函数缺少您分配的变量的 global 声明,这些变量旨在作为全局变量。

    【讨论】:

    • 我认为我的问题表述得不好。对不起。所以我编辑了我的问题,现在应该更清楚一点。我尝试将不和谐线程放在启动/停止中,但仍然出现错误。
    • @Paul 抱歉,但现在比以前更不清楚了。您正在访问init 的属性,您显示的脚本从未设置过这些属性。您还提到了您尝试过的内容,但是您没有显示该代码-我们怎么知道出了什么问题?您需要显示您正在运行的确切脚本,为了简洁起见,只需删除不和谐事件处理。
    • 真的很抱歉。我的母语不是英语。我尽力解释清楚。上面 postet 的代码就是我正在运行的确切代码。
    • @Paul 它不能是确切的代码,因为没有顶级代码会启动 asyncio 或不和谐或仅调用 discordfunction() 和其他代码。此外,由于缩进不一致,语法不正确,Python 永远不会接受它。如果您需要帮助,请发布您的实际代码并注意正确复制。
    • 我上次编辑代码时似乎并没有改变。所以现在它是我正在使用的 100% 准确的代码。我只删除了令牌。我不能在这里发布我的主脚本,因为它太长了,但我在主脚本中唯一要做的就是导入 start()stop() 函数,然后执行它们。
    猜你喜欢
    • 2021-08-04
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    • 2019-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多