Python多进程await连续处理

3
我正在使用基于事件的系统,运用了新版 Python 3.5 中的协程和 await。我注册事件,并由系统调用这些事件。
@event
aysnc def handleevent(args):
    # handle the event

我需要初始化一些类来处理工作(耗时)。然后调用实例方法,也很耗时(它们实际上使用Selenium浏览某些网站)。

理想情况下,我希望有以下代码:

# supposedly since this is multiprocessing this is a different driver per process
driver = None
def init():
    # do the heavy initialization here
    global driver
    driver = webdriver.Chrome()

def longworkmethod():
    ## need to return some data
    return driver.dolongwork()

class Drivers:
""" A class to handle async and multiprocessing"""
    def __init__(self, numberOfDrivers):
        self.pool = multiprocessing.Pool(processes=numberOfDrivers, initializer=init)       

    async def dowork(self, args):
        return self.pool.apply_async(longworkmethod, args=args)


### my main python class
drivers = Drivers(5)

@event
aysnc def handleevent(args):
    await drivers.dowork(args)

@event
aysnc def quit(args):
    ## do cleanup on drivers
    sys.exit(0)

这段代码不起作用,但我已经尝试了很多不同的方法,都无法实现我想要的功能。

它不一定要是这个确切的形式,但如果程序需要多进程,我该如何混合使用 await 和协程?

1个回答

2
虽然从技术上讲没有什么限制你混合使用 asynciomultiprocessing,但我建议避免这样做。这将增加很多复杂性,因为你最终需要为每个线程分配一个事件循环,并且来回传递信息会很棘手。只使用其中之一即可。 asyncio 提供了在另一个线程中运行任务的函数 - 例如AbstractEventLoop.run_in_executor。请参考以下答案: 或者你可以直接使用multiprocessing,因为selenium有一个阻塞(非asyncio)接口,但看起来你的一些代码已经使用了asyncio,所以也许还是使用上述方法吧。

我无法避免混合,因为我需要使用Selenium(多进程),而我正在使用的事件系统是严格的asyncio。但我会查看那些链接,看看能否让它们正常工作。 - leftsync
Selenium 是一个阻塞式的库,但这并不意味着你需要使用多进程。只需在主线程/事件循环中使用“run_in_executor”来处理阻塞部分,并将其他内容保留在主线程/事件循环中即可。 - Peter Gibson
那些链接似乎有所帮助。我应该像“get”一样使用run_in_executor来处理单个昂贵的调用,还是可以使用多个昂贵调用的大型昂贵函数?会有什么区别吗? - leftsync
@leftsync 这取决于你的调用结构。它们是否可以一次性全部运行,还是需要按顺序运行?你能支持多少个线程?Selenium 是线程安全的吗? - Peter Gibson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接