python中协程的用法

协程(Coroutine),也可以被称为微线程是一种用户态内的上下文切换技术。简而言之,其实就是通过一个线程实现代码块相互切换执行协程不是计算机提供,程序员人为创造。

实现协程有这么几种方法:

  • greenlet,早期模块。

  • yield关键字。

  • asyncio装饰器(py3.4)

  • async、await关键字(py3.5)【推荐】

1.1 greenlet实现协程

1
pip install greenlet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from greenlet import greenlet
 
 
def func1():
    print(1)        # 第1步:输出 1
    gr2.switch()    # 第3步:切换到 func2 函数
    print(2)        # 第6步:输出 2
    gr2.switch()    # 第7步:切换到 func2 函数,从上一次执行的位置继续向后执行
 
 
def func2():
    print(3)        # 第4步:输出 3
    gr1.switch()    # 第5步:切换到 func1 函数,从上一次执行的位置继续向后执行
    print(4)        # 第8步:输出 4
 
 
gr1 = greenlet(func1)
gr2 = greenlet(func2)
 
gr1.switch() # 第1步:去执行 func1 函数

1.2 yield关键字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def func1():
    yield 1
    yield from func2()
    yield 2
 
 
def func2():
    yield 3
    yield 4
 
 
f1 = func1()
for item in f1:
    print(item)

1.3 asyncio

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import asyncio
 
@asyncio.coroutine
def func1():
    print(1)
    # 网络IO请求:下载一张图片
    yield from asyncio.sleep(2)  # 遇到IO耗时操作,自动化切换到tasks中的其他任务
    print(2)
 
 
@asyncio.coroutine
def func2():
    print(3)
    # 网络IO请求:下载一张图片
    yield from asyncio.sleep(2) # 遇到IO耗时操作,自动化切换到tasks中的其他任务
    print(4)
 
 
tasks = [
    asyncio.ensure_future( func1() ),
    asyncio.ensure_future( func2() )
]
 
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

  注意:遇到IO阻塞自动切换

1.4 async & await关键字

  在python3.5及之后的关键字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import asyncio
 
async def func1():
    print(1)
    # 网络IO请求:下载一张图片
    await asyncio.sleep(2)  # 遇到IO耗时操作,自动化切换到tasks中的其他任务
    print(2)
 
 
async def func2():
    print(3)
    # 网络IO请求:下载一张图片
    await asyncio.sleep(2) # 遇到IO耗时操作,自动化切换到tasks中的其他任务
    print(4)
 
 
tasks = [
    asyncio.ensure_future( func1() ),
    asyncio.ensure_future( func2() )
]
 
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

 

协程函数,定义函数时候 async def 函数名

协程对象,执行 协程函数() 得到的协程对象。

1
2
3
4
async def func():
    pass
 
result = func()

  注意:执行协程函数创建协程对象,函数内部代码不会执行。

  如果想要运行协程函数内部代码,必须要将协程对象交给事件循环来处理。

1
2
3
4
5
6
7
8
9
10
import asyncio
 
async def func():
    print("快来搞我吧!")
 
result = func()
 <br># 事件循环
# loop = asyncio.get_event_loop()
# loop.run_until_complete( result )
asyncio.run( result ) # python3.7

示例1:

1
2
3
4
5
6
7
8
import asyncio
 
async def func():
    print("来玩呀")
    response = await asyncio.sleep(2)
    print("结束",response)
 
asyncio.run( func() )

示例2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import asyncio
 
 
async def others():
    print("start")
    await asyncio.sleep(2)
    print('end')
    return '返回值'
 
 
async def func():
    print("执行协程函数内部代码")
 
    # 遇到IO操作挂起当前协程(任务),等IO操作完成之后再继续往下执行。当前协程挂起时,事件循环可以去执行其他协程(任务)。
    response = await others()
 
    print("IO请求结束,结果为:", response)
     
asyncio.run( func() )

2.1 await  可等待的对象(协程对象、Future对象、Task对象 -> IO等待)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import asyncio
 
 
async def others():
    print("start")
    await asyncio.sleep(2)
    print('end')
    return '返回值'
 
 
async def func():
    print("执行协程函数内部代码")
 
    # 遇到IO操作挂起当前协程(任务),等IO操作完成之后再继续往下执行。当前协程挂起时,事件循环可以去执行其他协程(任务)。
    response1 = await others()
    print("IO请求结束,结果为:", response1)
     
    response2 = await others()
    print("IO请求结束,结果为:", response2)
     
asyncio.run( func()

  await就是等待对象的值得到结果之后再继续向下走。

2.2 Task对象

在事件循环中添加多个任务的。

Tasks用于并发调度协程,通过asyncio.create_task(协程对象)的方式创建Task对象,这样可以让协程加入事件循环中等待被调度执行。除了使用 asyncio.create_task() 函数以外,还可以用低层级的 loop.create_task()ensure_future() 函数。不建议手动实例化 Task 对象。

注意:asyncio.create_task() 函数在 Python 3.7 中被加入。在 Python 3.7 之前,可以改用低层级的 asyncio.ensure_future() 函数。

 

posted on   一先生94  阅读(311)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示