在python中,在两个threading.Thread
之间建立单向通信,将其称为线程a
和线程b
的惯用方式是什么。
a
是生产者,它不断为b
生成要消费的值。
b
是使用者,它读取a
生成的一个值,用协程处理该值,然后读取下一个值,依此类推。
插图:
q = very_magic_queue.Queue()
def worker_of_a(q):
while True:
q.put(1)
time.sleep(1)
a = threading.Thread(worker_of_a, args=(q,))
a.start()
async def loop(q):
while True:
# v must be processed in the same order as they are produced
v = await q.get()
print(v)
async def foo():
pass
async def b_main(q):
loop_fut = asyncio.ensure_future(loop(q))
foo_fut = asyncio.ensure_future(foo())
_ = await asyncio.wait([loop_fut, foo_fut], ...)
# blah blah blah
def worker_of_b(q):
asyncio.set_event_loop(asyncio.new_event_loop())
asyncio.get_event_loop().run_until_complete(b_main(q))
b = threading.Thread(worker_of_b, args=(q,))
b.start()
上面的代码当然不起作用,因为queue.Queue.get
不能被await
设置,并且asyncio.Queue
不能在另一个线程中使用。
我还需要一个从b
到a
的沟通渠道。
如果该解决方案也可以与gevent
一起使用,那就太好了。
谢谢:)
答案 0 :(得分:0)
您可以使用queue
模块中的同步队列,并将等待时间推迟到ThreadPoolExecutor
:
ios/2.5.10
答案 1 :(得分:0)
我有一个类似的问题-在线程和异步之间通信数据。我使用的解决方案是创建一个同步队列,并使用asyncio.sleep将异步获取和异步放置的方法添加到非阻塞状态。 这是我的队列类:
#class to provide queue (sync or asyc morph)
class queMorph(queue.Queue):
def __init__(self,qSize,qNM):
super().__init__(qSize)
self.timeout=0.018
self.me=f'queMorph-{qNM}'
#Introduce methods for async awaitables morph of Q
async def aget(self):
while True:
try:
return self.get_nowait()
except queue.Empty:
await asyncio.sleep(self.timeout)
except Exception as E:
raise
async def aput(self,data):
while True:
try:
return self.put_nowait(data)
except queue.Full:
print(f'{self.me} Queue full on put..')
await asyncio.sleep(self.timeout)
except Exception as E:
raise
要从线程(同步)从队列中放入/获取项目,请使用常规的q.get()和q.put()阻塞函数。 在异步循环中,使用不会阻塞的q.aget()和q.aput()。