python异步asyncio函数多线程操作run_in_executor和run_coroutine_threadsafe解析

刚接触异步asyncio,发现python文档一个版本一个变化,恼火。
东拼西凑终于解决了asyncio的多线程操作,记录下来。对于一个门外汉。太难了。

首先python3.9版本终于封装了一个多线程函数

asyncio.to_thread(func, /, *args, **kwargs) #函数直接开线程,传递参数。感觉这才像python

对于3.9版本以下,asyncio多线程实现就是,两个函数:

run_in_executor 和 run_coroutine_threadsafe

对应两种需求。
一个是主线程,直接新开线程,运行阻塞函数。方式就像之前写的同步代码一样。代码如下(用到了run_in_executor)

from concurrent.futures import ThreadPoolExecutor
import asyncio,time

def zusehanshu():   #测试的阻塞函数
           time.sleep(10)
           threadmingzi()
           return "after 10s"
           
async def returnfuture(): #测试新建线程
        loop=asyncio.get_event_loop() 
        newexecutor=ThreadPoolExecutor()
        future=await loop.run_in_executor(newexecutor,zusehanshu)#执行阻塞函数
        print(future)
        
def threadmingzi(): #查看当前线程名字
        import threading
        print("当前线程名字:",threading.current_thread())
        
asyncio.run(returnfuture())

输出结果:
当前线程名字: <Thread(ThreadPoolExecutor-0_0, started daemon 3252)>
after 10s(10s后输出)

上面可以看到,已经新建线程中运行了
第二种是主线程,直接新开线程,运行项目循环event-loop,推送函数到event-loop,达到多线程运行。(用到了run_coroutine_threadsafe)

import asyncio,time,threading

async def zusehanshu():   #测试的阻塞函数
        await asyncio.sleep(10)
        threadmingzi()
        
def threadmingzi(): #查看当前线程名字
        print("当前线程名字:",threading.current_thread())
        
def startloop(loop): #新建event-loop
        threadmingzi() #看一下线程名字
        asyncio.set_event_loop(loop)
        loop.run_forever()
        
xinjianloop=asyncio.new_event_loop()
threading.Thread(target=startloop,args=(xinjianloop,)).start()
asyncio.run_coroutine_threadsafe(zusehanshu(),xinjianloop)

输出结果:
当前线程名字: <Thread(Thread-1, started 7672)>
当前线程名字: <Thread(Thread-1, started 7672)>
上面可以看到,已经新建线程中运行了

总结:
asyncio原理就是遍历event-loop获取消息,是一个单线程阻塞函数。
遍历过程中遇到某个协程阻塞就会卡住,会一直等待结果返回,这时候就需要用到多线程防止阻塞。
通过上面两个方式,run_in_executor,与同步函数调用相似。用的比较习惯。
而run_coroutine_threadsafe新线程中建立新event-loop,可以动态添加协程,这个用途自己考虑了。

  • 10
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值