[英]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.