簡體   English   中英

Python - 結合多處理和 asyncio

[英]Python - Combining multiprocessing and asyncio

我正在嘗試將多處理與 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()

是因為它們運行在不同的進程上嗎? 請問我該如何解決這個問題?

發現問題了! 多處理創建實例的副本。 解決方案是創建一個Manager ,它共享實例本身。

編輯 [11/2/2020]:

import asyncio
from multiprocessing import Process, Manager

"""
These two functions will be created as separate processes.
"""
def task1(loop, shared_list):
    output = loop.run_until_complete(asyncio.gather(async1(shared_list)))

def task2(loop, shared_list):
    output = loop.run_until_complete(asyncio.gather(async2(shared_list)))

"""
These two functions will be called (in different processes) asynchronously.
"""
async def async1(shared_list):
    pass

async def async2(shared_list):
    pass

"""
Create the manager and start it up.
From this manager, also create a list that is shared by functions in different threads.
"""
manager = Manager()
manager.start()
shared_list = manager.list()

loop = asyncio.get_event_loop() # the event loop

"""
Create two processes.
"""
process1 = Process(target=task1, args=(loop, shared_list, ))
process2 = Process(target=task2, args=(loop, shared_list, ))

"""
Start the two processes and wait for them to finish.
"""
process1.start()
process2.start()

output1 = process1.join()
output2 = process2.join()

"""
Clean up
"""
loop.close()
manager.shutdown()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM