簡體   English   中英

使 Python 多處理池等待

[英]Making a Python multiprocessing Pool awaitable

我有一個應用程序需要執行一些基於 websocket stream 的處理器密集型工作。 我想通過多處理並行化 CPU 密集型位,但我仍然需要異步接口來處理應用程序的流處理部分。 為了解決這個問題,我希望制作一個可等待的 multiprocessing.AsyncResult 版本(multiprocessing.pool.Pool.submit_async 操作的結果)。 但是,我遇到了一些奇怪的行為。

只要池結果在我開始等待之前返回,我的新等待池結果(它是 asyncio.Future 的子類)就可以正常工作。 但是,如果我嘗試在池結果返回之前等待池結果,則程序似乎在 await 語句上無限期停止。

我已經使用 next( future.async ()) 檢查了異步迭代器結果,並且迭代器在池處理完成之前返回未來實例本身,並在之后引發 StopIterationError,正如我所期望的那樣。

代碼如下。

import multiprocessing
import multiprocessing.pool
import asyncio
import time

class Awaitable_Multiprocessing_Pool(multiprocessing.pool.Pool):
    def __init__(self, *args, **kwargs):
        multiprocessing.pool.Pool.__init__(self, *args, **kwargs)

    def apply_awaitably(self, func, args = list(), kwargs = dict()):
        return Awaitable_Multiprocessing_Pool_Result(
                self,
                func,
                args,
                kwargs)

class Awaitable_Multiprocessing_Pool_Result(asyncio.Future):
    def __init__(self, pool, func, args = list(), kwargs = dict()):
        asyncio.Future.__init__(self)
        self.pool_result = pool.apply_async(
                func,
                args,
                kwargs,
                self.set_result,
                self.set_exception)

    def result(self):
        return self.pool_result.get()

    def done(self):
        return self.pool_result.ready()

def dummy_processing_fun():
    import time
    print('start processing')
    time.sleep(4)
    print('finished processing')
    return 'result'

if __name__ == '__main__':
    async def main():
        ah = Async_Handler(1)
        pool = Awaitable_Multiprocessing_Pool(2)
        while True:
            future = pool.apply_awaitably(dummy_processing_fun, [])
            # print(next(future.__await__())) # would show same as print(future)
            # print(await future) # would stall indefinitely because pool result isn't in
            time.sleep(10) # NOTE: you may have to make this longer to account for pool startup time on the first iteration
            # print(next(future.__await__())) # would raise StopIteration
            print(await future) # prints 'result'
    asyncio.run(main())

我在這里遺漏了一些明顯的東西嗎? 我認為我擁有 awaitable 正常工作的所有基本元素,部分原因是我可以在某些情況下成功等待。 任何人有任何見解?

我不知道你為什么讓它如此復雜......下面的代碼怎么樣?

from concurrent.futures import ProcessPoolExecutor
import asyncio
import time

def dummy_processing_fun():
    import time
    print('start processing')
    time.sleep(4)
    print('finished processing')
    return 'result'

if __name__ == '__main__':
    async def main():
        pool = ProcessPoolExecutor(2)
        while True:
            future = pool.submit(dummy_processing_fun)
            future = asyncio.wrap_future(future)
            # print(next(future.__await__())) # would show same as print(future)
            # print(await future) # would stall indefinitely because pool result isn't in
            # time.sleep(5)
            # print(next(future.__await__())) # would raise StopIteration
            print(await future) # prints 'result'
    asyncio.run(main())

暫無
暫無

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

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