Передача инициализированного объекта discord.Client () в разные потоки - PullRequest
0 голосов
/ 28 марта 2020

В настоящее время я пишу своего бота с помощью библиотеки discord.py. Я хочу разделить функциональность бота на разные модули, которые работают в разных потоках. Надеюсь, что это не дубликат, так как я не нашел подобных вопросов.

Мне удалось передать инициализированный объект discord.Client() в разные потоки, но я столкнулся с несколькими проблемами. Кроме того, я вызываю и инициализирую потоки внутри события on_ready discord, поэтому client.run() не должен фактически блокировать потоки (как я думаю, я думаю, что я не прав).

Прежде всего, когда я проверяю все потоки в threads__pool (я создал этот список только для того, чтобы проверить, как работают потоки), я обнаружил, что ни один из них не работает, я имею в виду is_alive(), возвращающий False (active_count(), хотя возвращает 5).

Secondary потоки, кажется, работают как-то, я имею в виду один из них, потому что когда событие сообщения должно сработать, оно сработает только в одном потоке, который я запустил последним.

Я понимаю, что это недостаток моего асинхронного и многопоточного знания, но не могли бы вы помочь мне, потому что я не могу понять, что происходит не так.

Вот код:

import threading
import discord


client = discord.Client()
token  = "there will be token"

threads__pool = []

def main__one(client):
    @client.event
    async def on_message(message):
        print("Main__one got a message: Working!")
        if message.author == client.user:
            return
        else:
            print("Main__one answering!")
            await message.channel.send("Main__one retrieved some result")


def main__two(client):
    @client.event
    async def on_message(message):
        print("Main__two got a message: Working!")
        if message.author == client.user:
            return
        else:
            print("Main__two answering!")
            await message.channel.send("Main__two retrieved some result")


@client.event
async def on_ready():
    global packages

    print("Bot logged in and ready to initialize threads:")

    for package in packages:
        t = threading.Thread(target=package[0], args=package[1])
        t.run()
        threads__pool.append(t)
    print(threads__pool) # returns: [<Thread(Thread-2, initial)>, <Thread(Thread-3, initial)>] #
    for thread in threads__pool:
        print(thread.is_alive()) # returns: False #
    print(threading.active_count()) # returns: 5 #


packages = [[main__one, (client,)], [main__two, (client,)]]
client.run(token)

main__one и main__two являются основные функции (они будут вызывать другие функции внутри своих модулей) своих псевдомодулей. По сути, они просто имитируют активность.

Кроме того, когда я спам на канале раздора, я ожидаю, что бот сделает что-то подобное:

Main__two got a message: Working!
Main__two answering!
Main__one got a message: Working!
Main__one answering!

Но у меня есть:

Main__two got a message: Working!
Main__two answering!
Main__two got a message: Working!
...