-
-
Notifications
You must be signed in to change notification settings - Fork 32.8k
Description
Bug report
Bug description:
I am experiencing something that I think it's a bug in Python. I'm running a synchronous function in a ThreadPoolExecutor
and this function will sometimes put items to a queue. I have also an asynchronous function that runs in a loop and will consume items from that queue. The bug happens when I execute await queue.get()
when the queue is empty. If the queue has items, they will be popped nicely.
Below is a code snippet that, at least on my machine, have shown the bug.
import asyncio
from time import sleep
from concurrent.futures import ThreadPoolExecutor
loop = asyncio.get_event_loop()
queue = asyncio.Queue()
def putter_sync():
while True:
sleep(1)
print('will PUT to queue')
queue.put_nowait(1)
print('PUT to queue')
async def getter():
while True:
# await asyncio.sleep(1.1) # <-- if you uncomment this, it'll work fine! Items are put every 1 second,
# so by waiting 1.1 seconds you'll never try to get from an empty queue.
print('will GET from queue')
await queue.get()
print('GOT from queue')
executor = ThreadPoolExecutor(max_workers=1)
loop.run_in_executor(executor=executor, func=putter_sync)
loop.create_task(getter())
loop.run_forever()
This code will print this:
will GET from queue
will PUT to queue
PUT to queue
will PUT to queue
PUT to queue
will PUT to queue
PUT to queue
will PUT to queue
PUT to queue
Note that the get call never resolved. If I uncomment the sleep call, it runs as expected:
will PUT to queue
PUT to queue
will GET from queue
GOT from queue
will PUT to queue
PUT to queue
will GET from queue
GOT from queue
will PUT to queue
PUT to queue
will GET from queue
GOT from queue
will PUT to queue
PUT to queue
will GET from queue
GOT from queue
I also tried to replace the ThreadPoolExecutor
by a plain threading.Thread
, and the behaviour remained the same. To be honest, I don't actually know the difference between both, if anyone wants to explain it to me I'd appreciate. By the way, is this code even supposed to work? I don't think it is that bad...
CPython versions tested on:
3.11
Operating systems tested on:
Linux
Metadata
Metadata
Assignees
Labels
Projects
Status