Python 3.x Python异步IO队列未完成

Python 3.x Python异步IO队列未完成,python-3.x,python-asyncio,Python 3.x,Python Asyncio,我有一个生产者和三个消费者。每个使用者等待获取全局锁,然后才能继续。程序运行但未完成,并退出while循环。你能告诉我哪里出了问题吗 import asyncio import random async def produce(queue, n): for x in range(1, n + 1): # produce an item print('producing {}/{}'.format(x, n)) # simulate i/o

我有一个生产者和三个消费者。每个使用者等待获取全局锁,然后才能继续。程序运行但未完成,并退出while循环。你能告诉我哪里出了问题吗

import asyncio
import random

async def produce(queue, n):
    for x in range(1, n + 1):
        # produce an item
        print('producing {}/{}'.format(x, n))
        # simulate i/o operation using sleep
        await asyncio.sleep(random.random())
        item = str(x)
        # put the item in the queue
        await queue.put(item)

    # indicate the producer is done
    await queue.put(None)


async def consume(queue, lock):
    while True:
        item = await queue.get()
        if item is None:
            # the producer emits None to indicate that it is done
            break
        # wait for an item from the producer
        async with lock:
            # process the item
            print('consuming item {}...'.format(item))
            # simulate i/o operation using sleep
            await asyncio.sleep(0.3)


loop = asyncio.get_event_loop()
lock = asyncio.Lock()
queue = asyncio.Queue(loop=loop)
producer_coro = produce(queue, 10)
consumers = []
for _ in range(3):
    consumers.append(consume(queue, lock))
all_coroutines = []
all_coroutines.append(producer_coro)
all_coroutines.extend(consumers)
loop.run_until_complete(asyncio.wait(all_coroutines))
loop.close()

问题在于消费者:

        if item is None:
            # the producer emits None to indicate that it is done
            break
None
sentinel只由一个消费者拾取,其余的等待下一个值通过队列到达。一个简单的修复方法是将sentinel值返回到队列:

        if item is None:
            # The producer emits None to indicate that it is done.
            # Propagate it to other consumers and quit.
            await queue.put(None)
            break

或者,
product
可以让尽可能多的
None
哨兵排队等待消费者——但这需要生产者知道有多少消费者,这并不总是可取的。

问题在于消费者:

        if item is None:
            # the producer emits None to indicate that it is done
            break
None
sentinel只由一个消费者拾取,其余的等待下一个值通过队列到达。一个简单的修复方法是将sentinel值返回到队列:

        if item is None:
            # The producer emits None to indicate that it is done.
            # Propagate it to other consumers and quit.
            await queue.put(None)
            break

或者,
product
可以让尽可能多的
None
哨兵排队等待消费者——但这需要生产者知道有多少消费者,这并不总是可取的。

在提供的答案@user4815162342的基础上,尝试:

if item is None and queue.qsize() == 0:
    await queue.put(None)
    break

我遇到了一个问题,消费者还必须
排队。将()
放入同一队列以重新运行该函数,但在没有这两个条件的情况下,该函数在最后挂起。

添加到提供的答案@user4815162342,请尝试:

if item is None and queue.qsize() == 0:
    await queue.put(None)
    break
我遇到了一个问题,消费者也必须
排队。put()
到同一个队列才能重新运行函数,但在没有这两个条件的情况下,它在最后挂起