TRIO Lib очередь получить и поставить

Здравствуйте, я пытаюсь использовать трио с двумя асинхронными функциями и сообщение между ними. но это не запускает потребителя, и я действительно не понимаю, почему. Производитель хорошо отправляет в "очередь" и не отправляет ничего, как только он насыщен. Но потребитель не идет на это. Или я ошибаюсь? заранее спасибо

import time

import trio
async def producer(queue):
    while True:
        time.sleep(1)
        if queue.full() is False:
            queue.put_nowait(1)
            print(queue.full())
            print('put')

async def consumer(queue):
    while True:
        time.sleep(4)
        if queue.full() is True:
            print(queue.get_nowait())
            print(queue.full())
        print('get')

async def main():

    queue = trio.Queue(capacity=4)
    async with trio.open_nursery() as nursery:
        # Two producers
        nursery.start_soon(consumer, queue)
        nursery.start_soon(producer, queue)

trio.run(main)

1 ответ

Решение

Ваша проблема в том, что вы используете time.sleep, Если вы замените оба звонка time.sleep(...) с звонками в await trio.sleep(...)тогда твой пример работает.

Trio, как и все асинхронные библиотеки, может переключаться между задачами только в тех местах, где вы используете await, Это означает, что вы никогда не должны использовать блокирующие синхронные функции, такие как time.sleep - вместо этого вам нужно использовать асинхронные версии, которые предоставляет Trio, например trio.sleep, В вашем коде у вас нет awaits вообще, поэтому, какая бы задача ни выполнялась первой, она будет работать вечно и никогда не даст другой задаче возможности выполнить.

Обучающая программа Trio содержит более подробную информацию об этом.

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

Кроме того, к вашему сведению, ваш способ работы с очередью, вероятно, делает вещи более сложными, чем они должны быть:-). Я не думаю, что когда-либо использую queue.full(), а также put_nowait а также get_nowait есть законное использование, но они довольно редки. В большинстве случаев вам нужно только позвонить await queue.put(value) а также value = await queue.get() (или же print(await queue.get())или что угодно).

Другие вопросы по тегам