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)
posted @ 2019-08-02 19:35  ChanceySolo  阅读(313)  评论(0编辑  收藏  举报