about asyncio Queues , Use get() The elements in the queue have been ejected , and task_done() Just reduce the number of unfinished tasks .
This is the relevant information I found ( Although it is the queue of threads , But the same should be true of synergetics ):
https://stackoverflow.com/questions/1593299/python-queue-get-task-done-issue/1593330#1593330
No, queue.get() pops the item off the queue. After you do that, you can do whatever you want with it, as long as the producer works like it should and doesn’t touch it anymore. queue.task_done() is called only to notify the queue that you are done with something (it doesn’t even know about the specific item, it just counts unfinished items in the queue), so that queue.join() knows the work is finished.
after , I practiced it .
>>> import asyncio
>>> queue=asyncio.Queue(5)
>>> async def sb():
while 1:
await queue.put(1)
print(queue)
>>> async def cnm():
while 1:
await queue.get()
print(queue)
queue.task_done()
print(queue)
>>> async def main():
task=asyncio.create_task(sb())
await asyncio.sleep(5)
task.cancel()
asyncio.create_task(cnm())
>>> asyncio.run(main())
<Queue maxsize=5 _queue=[1] tasks=1>
<Queue maxsize=5 _queue=[1, 1] tasks=2>
<Queue maxsize=5 _queue=[1, 1, 1] tasks=3>
<Queue maxsize=5 _queue=[1, 1, 1, 1] tasks=4>
<Queue maxsize=5 _queue=[1, 1, 1, 1, 1] tasks=5>
<Queue maxsize=5 _queue=[1, 1, 1, 1] tasks=5>
<Queue maxsize=5 _queue=[1, 1, 1, 1] tasks=4>
<Queue maxsize=5 _queue=[1, 1, 1] tasks=4>
<Queue maxsize=5 _queue=[1, 1, 1] tasks=3>
<Queue maxsize=5 _queue=[1, 1] tasks=3>
<Queue maxsize=5 _queue=[1, 1] tasks=2>
<Queue maxsize=5 _queue=[1] tasks=2>
<Queue maxsize=5 _queue=[1] tasks=1>
<Queue maxsize=5 tasks=1>
<Queue maxsize=5>
You can see , Use get() after , The number of elements in the queue has decreased , however tasks There's no reduction , Use task_done() after tasks Just reduce .
see queue Properties of :
guess _unfinished_tasks It's above. tasks.
verification :
>>> async def cnm():
while 1:
await queue.get()
print(queue._unfinished_tasks)
queue.task_done()
print(queue._unfinished_tasks)
>>> asyncio.run(main())
<Queue maxsize=5 _queue=[1] tasks=1>
<Queue maxsize=5 _queue=[1, 1] tasks=2>
<Queue maxsize=5 _queue=[1, 1, 1] tasks=3>
<Queue maxsize=5 _queue=[1, 1, 1, 1] tasks=4>
<Queue maxsize=5 _queue=[1, 1, 1, 1, 1] tasks=5>
5
4
4
3
3
2
2
1
1
0
Guess right .
therefore , If you don't get the value from the queue and use task_done() If so, there will be elements in the queue , But the number of unfinished tasks is 0.
>>> queue.put_nowait(2)
>>> queue
<Queue at 0x24cf9965610 maxsize=5 _queue=[2] tasks=1>
>>> queue.task_done()
>>> queue
<Queue at 0x24cf9965610 maxsize=5 _queue=[2]>