协程

回顾一下进/线程

进程 计算机中最小的资源分配单位

线程 计算机中被cpu调度的最小单位

线程即操作系统的调度

对于操作系统来说,最小的可见单位即是线程

线程对比进程开销虽然小很多,但是开启/关闭线程仍需要开销

协程(本质是一条线程,操作系统不可见)

是由程序员操作的,而不是由操作系统调度的

多个协程的本质是一条线程,所以多个协程不能利用多核

出现的意义:多个任务中的io时间可以共享,当执行一个任务遇到io操作时可以将程序切换到另一个任务中继续执行

在有限的线程中,实现任务的并发,节省了一些调用操作系统创建/销毁线程的时间,并且协程的切换效率比线程切换效率要高

协程执行多个任务能让线程少陷入阻塞,使县城看起来很忙

线程陷入阻塞的次数越少,那么能够抢占的CPU资源就越多,程序效率看起来就越高

效率开销

协程的本质 于多个任务之间能够来回切换


协程模块:greenlet与gevent

greenlet模块

定义:对象名=greenlet(fun)

调用/启动:对象名.switch()

import time
from greenlet import greenlet #导入外部模块greenlet中的greenlet方法
def eat(): # 协程任务 协程函数
    print('start eating')
    time.sleep(1) # 睡1s
    print('end eating')
    g2.switch() #启动协程对象g2
def sleep(): # 协程任务 协程函数
    print('start sleeping')
    g1.switch() #启动协程对象g1
    time.sleep(1)
    print('end sleeping')

g1=greenlet(eat) # 定义协程对象g1
g2=greenlet(sleep) #定义协程对象g2
g1.switch() #启动协程g1

gevent模块

定义:对象名=gevent.spawn(fun)

调用/启动:仅在阻塞等待协程结束时生效,无阻塞则协程死亡

      对象名.join #启动一个协程

      gevent.joinall([g1,g2]) #启动列表中的所有协程

import time
import gevent
def eat():
    print('start eating')
    gevent.sleep(1) #gevent模块特有的,与time.sleep(1)相同效果,但gevent不支持time.sleep()
    print('end eating')
def sleep():
    print('start sleeping')
    gevent.sleep(1)
    print('end sleeping')
g1=gevent.spawn(eat)
g2=gevent.spawn(sleep)
gevent,joinall([g1,g2]) # 阻塞等待协程结束
import gevent
from gevent import monkey;monkey.path_all()
原文地址:https://www.cnblogs.com/lttlpp61007188/p/10846564.html