简体   繁体   English

如何在 Python 中使用 asyncio 和线程

[英]How to use asyncio with threading in Python

I am trying to use asyncio together with threading for a Discord Bot.我正在尝试将 asyncio 与线程一起用于 Discord Bot。 I've found this script which I changed to my needs:我找到了这个脚本,我根据自己的需要进行了更改:

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)

Starting the Script with the start() function works great.使用 start() 函数启动脚本效果很好。 Also stopping with the stop() function works somehow.使用 stop() 函数也可以以某种方式停止工作。 If I call the stop() function it prints: "False" so I am thinking that the thread was stopped.如果我调用 stop() 函数,它会打印:“False”,所以我认为线程已停止。 But if I then call the start() function I will get an error:但是如果我再调用 start() 函数,我会得到一个错误:

RuntimeError: threads can only be started once运行时错误:线程只能启动一次

This script is part of a big project so I am calling the functions from another script.这个脚本是一个大项目的一部分,所以我从另一个脚本调用函数。 But I think that shouldn't be the problem.但我认为这应该不是问题。

What is the problem?问题是什么? Thanks in advance.提前致谢。

You cannot re-start the existing thread, but you can start a new thread that runs the event loop.您不能重新启动现有线程,但可以启动一个运行事件循环的新线程。 You can achieve that by moving the assignment to discordthread to the start function.您可以通过将discordthread的分配移动到start函数来实现这一点。

And your call to call_soon_threadsafe is wrong.你对call_soon_threadsafe的调用是错误的。 You need to pass discordloop.stop to it, without parentheses.您需要将discordloop.stop传递给它,不带括号。 That refers to the actual function without calling it right away, and allows the loop thread to call it, which was intended:那是指不立即调用的实际函数,并允许循环线程调用它,其目的是:

discordloop.call_soon_threadsafe(discordloop.stop)

Finally, your init function is missing a global declaration for the variables you assign that are intended as globals.最后,您的init函数缺少您分配的用作全局变量的变量的global声明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM