对于单线程下,我们不可避免程序中出现io操作,但如果我们能在自己的程序中(即用户程序级别,而非操作系统级别)控制单线程下的多个任务能在一个任务遇到io阻塞时就切换到另外一个任务去计算,这样就保证了该线程能够最大限度地处于就绪态,即随时都可以被cpu执行的状态,相当于我们在用户程序级别将自己的io操作最大限度地隐藏起来,从而可以迷惑操作系统,让其看到:该线程好像是一直在计算,io比较少,从而更多的将cpu的执行权限分配给我们的线程。
协程的本质就是在单线程下,由用户自己控制一个任务遇到io阻塞了就切换另外一个任务去执行,以此来提升效率。为了实现它,我们需要找寻一种可以同时满足以下条件的解决方案:可以控制多个任务之间的切换,切换之前将任务的状态保存下来,以便重新运行时,可以基于暂停的位置继续执行;可以检测io操作,在遇到io操作的情况下才发生切换。
一、协程介绍
1、定义
协程是单线程下的并发,又称微线程。协程是一种用户态的轻量级的线程,即协程是由用户程序自己控制调度的。强调如下:(1)python的线程属于内核级别的,即由操作系统控制调度,如果遇到io或者执行时间过长,操作系统就会强迫要求交出cpu的执行权限,执行其他线程;(2)单线程内开启协程,一旦遇到io就会从应用程序的级别进行切换,从而提升效率。注意:一定是遇到IO才切
2、优点
优点如下:
(1)协程的切换的开销较小,属于程序级别的切换,操作系统无感知,因而更加的轻量级;(2)实现单线程内的并发,最大限度的利用cpu。
3、缺点
缺点如下:
(1)协程的本质是在单线程下,无法利用多核;(2)协程指的是单个线程,一旦协程遇到阻塞,则会阻塞整个线程。
二、greenlet模块
greenlet模块提供一种在多种任务之间来回切换的功能,这种切换手段非常便捷。如下例: