Python 协程

本文探讨了Python中的协程实现,如greenlet和asyncio模块,介绍了它们如何在IO密集场景下自动切换,提升并发效率。重点比较了协程、线程和进程的区别,并列举了相关技术应用如FastAPI和aiohttp。
摘要由CSDN通过智能技术生成

1. 多线程多进程、协程

  • 计算机中提供了:线程、进程 用于实现并发(真实存在)
  • 协程(Coroutine),是程序员通过代码搞出来的东西(非真实存在)
  • 协程也可以被称为微线程,是一种用户态内上下文切换技,其实就是通过一个线程实现代码块相互切换执行

2. Python中有多种方式可以实现协程

  • greenlet
    from greenlet import greenlet
    
    def func1():
    	print(1)
    	gr2.switch()  # 切换到func2函数
    	print(2)
    	gr2.switch()  # 切换到func2函数,从上一次执行的位置继续向后执行
    
    def func2():
    	print(3)
    	gr1.switch()  # 切换
    	print(4)
    
    gr1 = greenlet(func1)
    gr2 = greenlet(func2)
    gr1.switch()  # 去执行func1函数
    
  • yield
    def func1():
    	yield 1
    	yield from func2()
    	yield 2
    
    def func2():
    	yield 3
    	yield 4
    
    f1 = func1()
    for item in f1:
    	print(item)
    
  • 以上两种方法都实现了协程,但无实用意义,来回切换,反倒使程序执行速度更慢
  • 如果使用协程?不要让用户手动切换,而是遇到IO操作时能自动切换
  • Python3.4之后推出了asyncio模块 + Python3.5推出async、async语法,内部基于协程,并且遇到IO请求自动化切换
    import asyncio
    
    async def func1():
    	print(1)
    	await asyncio.sleep(2)
    	print(2)
    
    async def func2():
    	print(3)
    	await asyncio.sleep(2)
    	print(4)
    
    tasks = [
    	asyncio.ensure_future(func1()), 
    	asyncio.ensure_future(func2())
    ]
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait(tasks))
    
    import aiohttp
    import asyncio
    async def fetch(seesion, url):
    	print('发送请求:', url)
    	async with session.get(url, verify_ssl=False) as response:
    		content = await response.content.read()
    		file_name = url.rsplit('_')[-1]
    		with open(file_name, mode='wb') as file_object:
    			file_object.write(content)
    	
    async def main():
    	async with aiohttp.ClientSession() as session:
    		url_list = [
    			'http://www.autoimg.com/....',
    			'http://www.autoimg.com/....',
    			'http://www.autoimg.com/....'
    		]
    		tasks = [asyncio.create_task(fetch(session, url)) for url in url_list]
    		await asyncio.wait(tasks)
    		
    if __name__ = '__main__':
    	asyncio.run(main))
    
  • 在处理IO请求时,协程通过一个线程就可以实现并发操作

3. 协程、线程、进程的区别

  • 线程,是计算机中可以被CPU调度的最小单元
  • 进程,是计算机资源分配的最小单元(进程为线程提供资源)
  • 一个进程中可以有多个线程,同一个进程中的线程可以共享此进程中的资源
  • 由于CPython解释器中GIL的存在:
    • 线程,适用于IO密集型操作
    • 进程,适用于计算密集型操作
  • 协程,也可以被称为微线程,是一种用户态内的上下文切换技术,在开发中结合遇到IO自动切换,就可以通过一个线程实现并发操作
  • 故,在处理IO操作时,协程比线程更加节省开销(协程的开发难度大一些)
  • 支持协程的Python框架:FastAPI、Tornado、Sanic、Django 3、aiohttp等
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值