Table of Contents
协程简介
协程Libco库
libco的特性
PS:CGI框架
PS:Lambda表达式
协程这个概念其实在《操作系统》系统里面应该有了解过,进程(process),线程(thread),协程(routinue),其中大部分博客,论文对进程和线程都有介绍,协程的介绍却比较少。协程其实是在线程里面跑的,比线程更细粒度。线程里面其实是有当前执行的上下文信息,里面装了当前执行的位置,将要执行什么代码。如果我们有多个这样的上下文,并且可以在里面各种跳转,就类似于我们在线程里面实现了一种更细粒度的“线程”。你可以把这种上下文理解成一个函数,相当于有A,B两个函数,我在执行A的时候,还没执行完,然后暂停了一下,去执行B,然后还没等B执行完,又暂停一下,去继续执行A,就像线程调度一样,但这个不是线程,因为A和B不能并发(有些框架其实是可以的,例如,在上一家公司用的一个叫BRPC的框架,后面我会写博客介绍这个框架,这里的协程就是指在一个线程里面的那种协程),也就是A执行的时候,B不能执行,B执行的时候,A不能执行,所以这种协程不用考虑锁的问题,因为不会发生竞争。另外和线程不同的是,这种协程调度不是由操作系统来调度的,是由开发者,也就是人通过代码来调度的。线程是操作系统执行的最小单位,对于操作系统来说,他只能看到线程,不知道这个线程里面是怎么调度的。这是这种“子程序”或者“运行模式”(我也不知道用什么名词比较合适)就是协程。
那么协程的优势在哪儿呢,看起来协程并不能并发,似乎用处不大。但回想一下我们在一些耗时操作的时候,例如网络请求,有段时间我们会等待请求回来,这种等待其实就是一种CPU资源的浪费。这时候如果有协程,我们在知道要等待的时候,在代码里面切换一下,去执行其他操作,等那个请求回来了,我们再切回去执行那个返回的结果,这样不就把等待那部分时间给利用起来了么。如果是在多线程里面,一个线程的请求没回来,我们可能用一个thread_yield,或者wait的方法,让这个线程休眠,但这样中间就会有一次线程切换,会浪费一些消耗,而协程切换就不会有这个影响,因为在操作系统看来,这全部都是在一个线程里面去完成的。所以这也是协程的最大的优势:协程切换开销远小于线程,进程切换。
https://github.com/Tencent/libco
Libco是ac / c ++协程库,在微信服务中广泛使用。自2013年以来,它已在成千上万的计算机上运行。
通过与libco链接,您可以轻松地将同步后端服务转换为协程服务。与多线程方法相比,协程服务将提供出色的并发性。使用系统挂钩,您可以轻松地以同步方式进行编码,但可以异步执行。
您还可以使用co_create / co_resume / co_yield接口创建异步后端服务。这些界面将使您更好地控制协程。
通过libco复制堆栈模式,您可以轻松地建立支持数千万tcp连接的后端服务。
作者:sunnyxu(sunnyxu@tencent.com),leiffyli(leiffyli@tencent.com),dengoswei@gmail.com(dengoswei@tencent.com),sarlmolchen(sarlmolchen@tencent.com)
CGI,一言以蔽之——协议。为了和普通的网络协议做区分,我们可以称之为接口协议。所谓协议就是各方约定,达成共识的一种规则。比如中国公路靠右行驶,这就是公路的协议。网络协议约定的是逐字节的含义,大家遵守,就能方便解析,理解。CGI约定的不是逐字节的语义,而是一个个kv(不完全是kv,但可以大概这么理解)。用一个不太恰当的比喻来形容,网络协议描述的单位是数组,而CGI接口协议描述的是map。CGI是比较原始的开发动态网站的方式。
CGI,SWGI区别
cgi通过环境变量,输入输出流完成web server与处理逻辑的http协议的交互,由于是基于流方式,所以各种语言都可以写cgi程序。wsgi是将web server参数python化,封装为request对象传递给apllication命名的func对象并接受其传出的response参数,由于其处理了参数封装和结果解析,才有python世界web框架的泛滥,在python下,写web框架就像喝水一样简单:)
Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。