04. 协程(微线程)

一、协程基础#

1. 定义#

纤程、微线程。

是非抢占式多任务产生子程序的计算机组件。协程允许不同入口在同一位置暂停或者开始。简单来说,协程就是可以暂停执行的函数

典型的抢占式设计,暂停执行的时候就会开辟新的管道

yield是实现上述函数的基本关键字,包含yield的函数可以暂停执行,并且返回函数内部,继续执行

def fun():
    print("启动生成器")
    yield 1
    print("生成器玩成")

msg = fun()
print(next(msg))
print(next(msg))

以上代码会出现报错StopIteration

next 希望得到下一个迭代值,如果有记录上下文,等待再次执行

协程的本质就是一个单进程程序,不会使用计算机多核资源,但是可以在应用层形成多个函数任务都被执行的形态,以处理多个任务。

资源占用少

2. 原理#

协程是记录一个函数的上下文栈帧,协程调度切换时会将记录的上下文保存,在切换回来时进行调取,回复原有的执行内容,以便从暂停的位置继续执行。

3.优缺点#

3.1 优点#

  1. 协程完成多任务占用计算机资源少
  2. 协程在多任务间切换开销小
  3. 协程是单线程无需进行同步互斥处理

3.2 缺点#

  1. 协程无法利用计算机多核资源

4.协程模块#

4.1 greenlet#

4.1.1 安装

sudo pip install greenlet

4.1.2 函数

greenlet.greenlet(func)

功能: 创建协程对象

参数: 协程函数

g.switch()

功能:执行对应的协程函数

from greenlet import greenlet

def func1():
    print('执行func')
    g2.switch()
    print('结束func')
    
def func2():
    print('执行func2')
    g1.switch()
    print('结束func2')
    
# 生成协程对象
g1 = greenlet(func1)
g2 = greenlet(func2)

g1.switch() # 执行func1协程

4.2 gevent#

4.2.1 安装

sudo pip install gevent

4.2.2 函数

gevent.spawn(func,argv,...)

功能:生成协程对象

参数: func 协程函数

​ argv 给func传递参数

返回值: 协程对象

gevent.joinall(list)

功能:阻塞等待协程事件执行完毕

参数:list 协程对象列表

gevent.sleep(sec)

功能:gevent睡眠阻塞

参数:睡眠时间

gevent协程只有在遇到gevent指定的阻塞行为才会触发协程之间的跳转

4.2.3 gevent 阻塞触发方法

from gevent import monkey

e.g. 将socket模块下的所有阻塞转换为gevent阻塞

monkey.patc_socket()

from socket import *

注意:脚本插件函数必须要在导入模块之前执行

import gevent
from gevent import monkey
monkey.patch_all() # 执行脚本函数,修改原有阻塞

from socket import *

# 客户端处理函数
def handler(c):
    while True:
        data = c.recv(1024)
        if not data:
            break
        print(data.decode())
        c.send(b'OK')
    c.close()

s = socket()
s.bind(('0.0.0.0',8888))
s.listen(5)

while True:
    c, addr = s.accept()
    print("来自%s的连接"%addr[0])
    # handler(c) # 循环方案
    gevent.spawn(handler,c)

作者:ChanceySolo

出处:https://www.cnblogs.com/chancey/p/11290825.html

版权:本作品采用「ChanceySolo-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   ChanceySolo  阅读(318)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示