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
, В вашем коде у вас нет await
s вообще, поэтому, какая бы задача ни выполнялась первой, она будет работать вечно и никогда не даст другой задаче возможности выполнить.
Обучающая программа Trio содержит более подробную информацию об этом.
К сожалению, Трио не замечает этого и предупреждает вас... Я только что подал вопрос, который, надеюсь, добавит.
Кроме того, к вашему сведению, ваш способ работы с очередью, вероятно, делает вещи более сложными, чем они должны быть:-). Я не думаю, что когда-либо использую queue.full()
, а также put_nowait
а также get_nowait
есть законное использование, но они довольно редки. В большинстве случаев вам нужно только позвонить await queue.put(value)
а также value = await queue.get()
(или же print(await queue.get())
или что угодно).