对于IO密集型的程序,一般比较高效的做法是选择异步来实现,因为使用异步的方法更容易写出高效的程序。然而使用异步的话,经验较少的人往往会使自己的程序结构变得很混乱,进而导致程序的可读性变差。记得有人说过,在硬件飞速发展的现在,程序的可读性和可维护性的重要性在不断提高,甚至有一种更激进的说法,程序的可读性是第一位的。从Boost的1.54版本开始,coroutine引入了一种新型的协程,stackfull协程,之前Boost库的协程是stackless协程。对于这两者的区别,我仅知道stackless协程不可以使用局部变量,只能通过全局变量和类内部的变量实现信息传递,而stackfull协程则可以使用全局变量。可能是二者的实现方法不同吧,对于二者的效率差别,几乎可以忽略。哦,忘了介绍什么是协程了。。。

  与子例程一样,协程也是一种程序组件。相对子例程而言,协程更为一般和灵活,但在实践中使用没有子例程那样广泛。协程源自SimulaModula-2语言,但也有其他语言支持。协程更适合于用来实现彼此熟悉的程序组件,如合作式多任务迭代器无限列表管道

  由于协程不如子例程那样被普遍所知,最好对它们作个比较。子例程的起始处是惟一的入口点,一旦退出即完成了子例程的执行,子例程的一个实例只会返回一次。协程可以通过yield来调用其它协程。通过yield方式转移执行权的协程之间不是调用者与被调用者的关系,而是彼此对称、平等的。协程的起始处是第一个入口点,在协程里,返回点之后是接下来的入口点。子例程的生命期遵循后进先出(最后一个被调用的子例程最先返回);相反,协程的生命期完全由他们的使用的需要决定。

  这里有一个很重要的特点,协程可以多次进入和退出,并且下一次进入的地方正好是上一次退出的地方。举个例子,

void fun()
{
do1(); //1 do2(); //2 do3(); //3
}

对于这样的一个函数过程,如果使用协程的方法实现的话,那么这个调用过程可以在do1的地方退出,然后在下一次进入,并且进入后直接从do2处开始执行。

  那么一个协程适合做什么呢?你想,对于IO密集型程序中,IO系统调用往往不会很及时的返回,如果你选择使用同步的方法,你的程序往往可能会是下面的样子:

void fun()
{
read(buf, ...);
write(buf, ...);
}

而如果你使用的是异步的话,你的程序可能会是下面的样子:

void fun()
{
async_read(buf, read_handler);
} void read_handler()
{
do_somethiing//...
async_write(buf, write_handler);
} void write_handler()
{
do_something//..
}

这样的调用层次少的话,还可以接受,一旦多了,整个程序读起来会让人十分的崩溃。协程的出现解决了这个问题。

而如果你选择异步+协程的方法,你的程序不用等,并且会变得跟同步程序一样可读性很好。下面用我的一个简单的例子来说明stackfull协程的使用方法。程序主要实现了从控制台实现异步读和异步写的功能。代码十分简单,就不用说明了。(oh, 博客园的代码缩进简直就是shit, 算了直接贴代码地址吧)。

我一共用了两种方法实现该功能作为对比,一种是仅使用异步的方法,一种是适用异步+协程的方法。从整个代码的组织结构你可以看出使用了协程之后,整个程序的可读性大幅度提高,对于性能呢,你完全不用担心,几乎差别可以忽略。(注:这两份代码都是linux平台实现的,控制台异步输入输出的方法对于windows不适用。)

异步的代码地址:https://github.com/xiaopeifeng/CodeTricks/blob/master/async_say_love_fxp.cc

协程的代码地址:https://github.com/xiaopeifeng/CodeTricks/blob/master/spawn_say_love_fxp.cc

协程的具体实现方法,以后再做研究。

最新文章

  1. ABP源码分析三十七:ABP.Web.Api Script Proxy API
  2. 解决eclipse Maven 主项目不能刷新maven
  3. POJ 3255 Roadblocks(A*求次短路)
  4. c3p0配置 initialPoolSize 和minPoolSize 可以设为0吗?设0有坏处吗?
  5. eclipse js卡顿
  6. SQLServer2008 行转列
  7. 2016 Multi-University Training Contest 1 Necklace 环排+二分匹配
  8. Aix db2 经user a using b连接时报SQL30082N Security processing failed with reason "42"
  9. python 逻辑运算 ‘and’ ,'or' 在实战中的作用,代替if语句。
  10. DS博客作业01-日期抽象数据类型设计和实现
  11. linux下C获取文件的大小
  12. Maze-hdu4035(DP求概率)
  13. C# 单例模式和窗体的单例打开方法
  14. Oracle 常用sql整理
  15. 微信小程序之 ----API接口
  16. 3D打印切片软件介绍
  17. eclipse中设置自定义文档签名(工具)
  18. 解读linux中用户密码规则及忘记root口令的破解(思路)
  19. SQLite的使用
  20. 3、列表 list

热门文章

  1. js框架设计1.4类型判断
  2. Android错误
  3. MAGENTO - APACHE SOLR INTEGRATION - PART II (SETUP)
  4. poj1988_Cube Stacking
  5. 第一天:安装nodejs
  6. 【Xcode 4 无法打开 Xcode 5 DP 打开过的工程文件 解决方法】
  7. 安天AVLTeam送福利喽~~
  8. Redis的缓存策略和主键失效机制
  9. UnrealEd3视图导航
  10. swift动画小试牛刀