Python-结合多处理和异步

时间:2018-07-03 12:10:51

标签: python python-multiprocessing python-asyncio

我正在尝试将异步处理与多处理结合起来。该程序有两个主要组成部分-一个用于流式传输/生成内容的内容,另一个用于消费内容的内容。

我要做的是创建多个进程以利用多个CPU内核-一个用于流侦听器/生成器,另一个用于使用者,以及一个简单的在使用者停止时关闭所有程序。

>

到目前为止,我的方法一直是创建流程并启动它们。每个这样的过程都会创建一个异步任务。一旦所有进程开始,我将运行asyncio任务。我到目前为止(精简)的是:

def consume_task(loop, consumer):
    loop.create_task(consume_queue(consumer))

def stream_task(loop, listener, consumer):
    loop.create_task(create_stream(listener, consumer))

def shutdown_task(loop, listener):
    loop.create_task(shutdown(consumer))

async def shutdown(consumer):
    print("Shutdown task created")
    while not consumer.is_stopped():
        print("No activity")
        await asyncio.sleep(5)
    print("Shutdown initiated")
    loop.stop()

async def create_stream(listener, consumer):
    stream = Stream(auth, listener)
    print("Stream created")
    stream.filter(track=KEYWORDS, is_async=True)
    await asyncio.sleep(EVENT_DURATION)
    print("Stream finished")
    consumer.stop()

async def consume_queue(consumer):
    await consumer.run()

loop = asyncio.get_event_loop()

p_stream = Process(target=stream_task, args=(loop, listener, consumer, ))
p_consumer = Process(target=consume_task, args=(loop, consumer, ))
p_shutdown = Process(target=shutdown_task, args=(loop, consumer, ))
p_stream.start()
p_consumer.start()
p_shutdown.start()

loop.run_forever()
loop.close()

问题是一切都挂起了(或阻塞了?)-实际上没有任何任务在运行。我的解决方案是将前三个功能更改为:

def consume_task(loop, consumer):
    loop.create_task(consume_queue(consumer))
    loop.run_forever()

def stream_task(loop, listener, consumer):
    loop.create_task(create_stream(listener, consumer))
    loop.run_forever()

def shutdown_task(loop, listener):
    loop.create_task(shutdown(consumer))
    loop.run_forever()

这确实可以运行。但是,consumerlistener对象无法通信。举一个简单的例子,当create_stream函数调用consumer.stop()时,使用者不会停止。即使更改了consumer类变量,也不会进行更改-例如,共享队列仍然为空。这就是我创建实例的方式:

queue = Queue()
consumer = PrintConsumer(queue)
listener = QueuedListener(queue, max_time=EVENT_DURATION)

请注意,如果我不使用流程,而仅使用asyncio任务,那么一切都会按预期进行,因此我认为这不是参考问题:

loop = asyncio.get_event_loop()
stream_task(loop, listener, consumer)
consume_task(loop, consumer)
shutdown_task(loop, listener)
loop.run_forever()
loop.close()

是因为它们运行在不同的进程上吗?我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

发现了问题!多重处理创建实例的副本。解决方案是创建一个Manager,它可以共享实例本身。