Two coroutintes in code below, running in different threads, cannot communicate with each other by asyncio.Queue. After the producer inserts a new item in asyncio.Queue, the consumer cannot get this item from that asyncio.Queue, it gets blocked in method await self.n_queue.get().
I try to print the ids of asyncio.Queue in both consumer and producer, and I find that they are same.
import asyncio
import threading
import time
class Consumer:
    def __init__(self):
        self.n_queue = None
        self._event = None
    def run(self, loop):
        loop.run_until_complete(asyncio.run(self.main()))
    async def consume(self):
        while True:
            print("id of n_queue in consumer:", id(self.n_queue))
            data = await self.n_queue.get()
            print("get data ", data)
            self.n_queue.task_done()
    async def main(self):
        loop = asyncio.get_running_loop()
        self.n_queue = asyncio.Queue(loop=loop)
        task = asyncio.create_task(self.consume())
        await asyncio.gather(task)
    async def produce(self):
        print("id of queue in producer ", id(self.n_queue))
        await self.n_queue.put("This is a notification from server")
class Producer:
    def __init__(self, consumer, loop):
        self._consumer = consumer
        self._loop = loop
    def start(self):
        while True:
            time.sleep(2)
            self._loop.run_until_complete(self._consumer.produce())
if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    print(id(loop))
    consumer = Consumer()
    threading.Thread(target=consumer.run, args=(loop,)).start()
    producer = Producer(consumer, loop)
    producer.start()
id of n_queue in consumer: 2255377743176
id of queue in producer  2255377743176
id of queue in producer  2255377743176
id of queue in producer  2255377743176
I try to debug step by step in asyncio.Queue, and I find after the method self._getters.append(getter) is invoked in asyncio.Queue, the item is inserted in queue self._getters. The following snippets are all from asyncio.Queue.
    async def get(self):
        """Remove and return an item from the queue.
        If queue is empty, wait until an item is available.
        """
        while self.empty():
            getter = self._loop.create_future()
            self._getters.append(getter)
            try:
                await getter
            except:
                # ...
                raise
        return self.get_nowait()
When a new item is inserted into asycio.Queue in producer, the methods below would be invoked. The variable self._getters has no items although it has same id in methods  put() and set().
    def put_nowait(self, item):
        """Put an item into the queue without blocking.
        If no free slot is immediately available, raise QueueFull.
        """
        if self.full():
            raise QueueFull
        self._put(item)
        self._unfinished_tasks += 1
        self._finished.clear()
        self._wakeup_next(self._getters)
    def _wakeup_next(self, waiters):
        # Wake up the next waiter (if any) that isn't cancelled.
        while waiters:
            waiter = waiters.popleft()
            if not waiter.done():
                waiter.set_result(None)
                break
Does anyone know what's wrong with the demo code above? If the two coroutines are running in different threads, how could they communicate with each other by asyncio.Queue?
 
    