协程是用户相互协作的线程,又称微线程,本身还是线程。
线程是系统级别的,它们是由操作系统调度;协程是程序级别的,由程序员根据需要自己调度。我们把一个线程中的一个个函数叫做子程序,那么子程序在执行过程中可以中断去执行别的子程序;别的子程序也可以中断回来继续执行之前的子程序,这就是协程。也就是说同一线程下的一段代码<1>执行着执行着就可以中断,然后跳去执行另一段代码,当再次回来执行代码块<1>的时候,接着从之前中断的地方开始执行。
优点:
并没有说协程就一定不加锁,协程本身的某些功能实现也是通过线程池实现的;就算没有用到其他线程,假如一个操作需要连续性地完成,那么也是需要借助锁的概念。asyncio 和 gevent 库中都有实现 threading 下的一些同步机制,比如 Lock、Semaphore 等,虽然和 threading 的底层的实现不同,但是同样起到了保证一些操作顺序、不会被打断地执行。
Gevent: (实现遇到IO自动切换)
Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程。 Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。
gevent是一个基于协程(coroutine)的Python网络函数库,通过使用greenlet提供了一个在libev事件循环顶部的高级别并发API。
主要特性有以下几点:
基于libev的快速事件循环,Linux上面的是epoll机制
基于greenlet的轻量级执行单元
API复用了Python标准库里的内容
支持SSL的协作式sockets
可通过线程池或c-ares实现DNS查询
通过monkey patching功能来使得第三方模块变成协作式
Monket patching
Python的运行环境允许我们在运行时修改大部分的对象,包括模块、类甚至函数。虽然这样做会产生“隐式的副作用”,而且出现问题很难调试,但在需要修改Python本身的基础行为时,Monkey patching就派上用场了。Monkey patching能够使得gevent修改标准库里面大部分的阻塞式系统调用,包括socket,ssl,threading和select等模块,而变成协作式运行。
Semaphore和BoundedSemphore 都是信号量类, 有进/线/协程获得信号量时(即acquire())计数器-1,释放信号量时(release())技术器+1,计数器为0的时候其他线/进/协程就被阻塞无法获得信号量。当计数器为设定好的上限的时候BoundedSemaphore就无法进行release()操作,Semaphore没有这个限制。
参考文献:https://www.cnblogs.com/zhangyux/p/6195860.html