引子:

  之前学习过了,线程,进程的概念,知道了在操作系统中进程是资源分配的最小单位,线程是CPU调度的最小单位.按道理来说我们已经算是把CPU的利用率提高很多了.但是我们知道无论是创建多进程还是创建多线程来解决问题,都要消耗一定的时间来创建进程,创建线程,以及管理他们之间的切换.

  随着我们对于效率的最求不断提高,基于单线程来实现并发又成为一个新的课题.即只用一个主线程的情况下实现并发.这样就可以节省创建线程进程所消耗的时间.

  并发的本质: 切换+保存状态

  cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是任务发生了阻塞,另外一种情况是该任务计算时间过长

  Python之路--协程/IO多路复用

  对于单线程下,我们不可避免程序中出现io操作,但如果我们能在自己的程序中(即用户程序级别,而非操作系统级别)控制单线程下的多个任务能在一个任务遇到io阻塞时就切换到另外一个任务去计算,这样就保证了该线程能够最大限度地处于就绪态,即随时都可以被cpu执行的状态,相当于我们在用户程序级别将自己的io操作最大限度地隐藏起来,从而可以迷惑操作系统,让其看到:该线程好像是一直在计算,io比较少,从而更多的将cpu的执行权限分配给我们的线程。

  协成的本质就是在单线程下,由用户自己控制一个任务遇到IO阻塞就切换另一个任务去执行,一次来提升效率.

#可以控制对个任务之间的切换,切换之前将任务的状态保存下来,以便重新运行时,可以基于暂停的位置继续执行.
#作为1的补充;可以检测IO操作,在遇到IO操作的情况下才发生切换

协程:是单线程下的并发,又称为为线程. 协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的.

协程特点:

  必须在只有一个单线程里实现并发

  修改共享数据不需加锁

  用户程序里自己保存多个控制流的上下文栈

  一个协程遇到IO操作自动切换到其他协程

Greenlet模块

安装:pip3 install greenlet

from greenlet import greenlet

def eat(name):
    print('%s eat 1'%name)
    g2.switch('egon')
    print('%s eat 2'%name)
    g2.switch()
def play(name):
    print('%s play 1' %name)
    g1.switch
    print('%s play 2' %name)

g1 = greenlet(eat)
g2 = greenlet(play)

g1.switch('egon')#可以在第一次switch时传入参数,以后都不需要
greenlet实现状态切换

相关文章: