• asyncio时间循环中运行阻塞任务


     场景:

    在某个异步循环中 需要执行某个阻塞任务(例如文件读写., 保存图片等)

    如果这个时候直接在异步事件循环中直接运行, 那么所有任务都会阻塞在这里, 明显是不行的

    解决方案:

    https://docs.python.org/3/library/asyncio-eventloop.html#executing-code-in-thread-or-process-pools

    import concurrent.futures
    
    def blocking_io():
        # File operations (such as logging) can block the
        # event loop: run them in a thread pool.
        with open('/dev/urandom', 'rb') as f:
            return f.read(100)
    
    # 在某个异步事件循环中
    async def main():
        loop = asyncio.get_running_loop()  # 获取当前事件循环
    
        result = await loop.run_in_executor(None, blocking_io)
    
        with concurrent.futures.ThreadPoolExecutor() as pool:
              result = await loop.run_in_executor(
                pool, blocking_io)
              print('custom thread pool', result)
    
    asyncio.run(main())

    loop.run_in_exeutor(pool, func)

    pool为线程池 在python里面为concurrent.futures.ThreadPoolExecutor的实例

    func为需要运行的同步函数 如果需要传入参数, 要用functools.partial(func, *arg, **kwargs)  传入.

    运行之后, 则会在不阻塞异步时间循环的情况下 ,在新的线程中运行func 结束之后用await接收

    如果一开始不指定线程池,那么官方文档中说的是默认线程池

    这里的默认线程池可以用

    loop.set_default_executor(executor)

    来指定

    如果一开始也不指定, 那么经过阅读源码之后 可知:

        def run_in_executor(self, executor, func, *args):
            self._check_closed()
            if self._debug:
                self._check_callback(func, 'run_in_executor')
            if executor is None:
                executor = self._default_executor
                if executor is None:
                    executor = concurrent.futures.ThreadPoolExecutor()
                    self._default_executor = executor
            return futures.wrap_future(
                executor.submit(func, *args), loop=self)

    他会帮我们自动启用一个线程池, 丢进去运行.

    总之异步的时间循环中如果要加入阻塞型代码,  千万不能直接阻塞, 用此法可破.

  • 相关阅读:
    UVALive
    hdu 3869 Color the Simple Cycle (kmp+polya计数)
    zoj 3794 Greedy Driver
    zoj 3795 Grouping
    ASP.NET Core 简介
    ASP.NET Core 基础教程
    iOS ShareSDK Scheme
    微博授权失败 redirect_uri_mismatch
    集成友盟分享SDK报错
    获取设备实际宽度
  • 原文地址:https://www.cnblogs.com/btxlc/p/12616288.html
Copyright © 2020-2023  润新知