协程三篇之一(协程初接触)
来源:互联网 发布:编程世界 编辑:程序博客网 时间:2024/06/05 22:45
赖勇浩(http://laiyonghao.com)
协程,又称微线程和纤程等,据说源于 Simula 和 Modula-2 语言(我没有深究,有错请指正),现代编程语言基本上都有支持,比如 Lua、ruby 和最新的 Google Go,当然也还有最近很让我惊艳的 falcon。协程是用户空间线程,操作系统其存在一无所知,所以需要用户自己去做调度,用来执行协作式多任务非常合适。其实用协程来做的东西,用线程或进程通常也是一样可以做的,但往往多了许多加锁和通信的操作。
下面是生产者消费者模型的基于抢占式多线程编程实现(伪代码):
// 队列容器
var q := new queue
// 消费者线程
loop
lock(q)
get item from q
unlock(q)
if item
use this item
else
sleep
// 生产者线程
loop
create some new items
lock(q)
add the items to q
unlock(q)
由以上代码可以看到线程实现至少有两点硬伤:
1、对队列的操作需要有显式/隐式(使用线程安全的队列)的加锁操作。
2、消费者线程还要通过 sleep 把 CPU 资源适时地“谦让”给生产者线程使用,其中的适时是多久,基本上只能静态地使用经验值,效果往往不由人意。
而使用协程可以比较好的解决这个问题,下面来看一下基于协程的生产者消费者模型实现(伪代码):
// 队列容器
var q := new queue
// 生产者协程
loop
while q is not full
create some new items
add the items to q
yield to consume
// 消费者协程
loop
while q is not empty
remove some items from q
use the items
yield to produce
可以从以上代码看到之前的加锁和谦让 CPU 的硬伤不复存在,但也损失了利用多核 CPU 的能力。所以选择线程还是协程,就要看应用场合了。下面简单谈一下协程常见的用武之地,其中之一是状态机,能够产生更高可读性的代码;还有就是并行的角色模型,这在游戏开发中比较常见;以及产生器,有助于对输入/输出和数据结构的通用遍历。
协程虽然如此之好,看是很长时间以来,因为受到基于堆栈的子例程实现的限制,并没有多少语言在其实语言或库中支持协程,所以线程作为一个替代者(当然,线程也有其超越协程之处)被广泛接受了。但是在今天,很多语言都内建了协程的支持,甚至是 C/C++ 语言。MS Windows 2000 以后的版本,都支持所谓的 Fiber,即纤程,其实就是协程的别称;在开源平台,POSIX 标准也定义了协程相关的标准,GNU Portable Threads 实现了跨平台的用户空间线程,即协程的另一种别称。在这百花齐放的时节,正是我们好好学习和利用它的时机。
接下来我将在第二篇中谈谈游戏中试用协程的三个场合。
- 协程三篇之一(协程初接触)
- 接触VC之一:WinSDK
- 接触VC之一:WinSDK
- 性能测试初接触之一
- LUA学习之一 初次接触
- ADO第一次亲密接触 -- ADO开发实践之一
- ADO第一次亲密接触 -- ADO开发实践之一
- ADO第一次亲密接触 -- ADO开发实践之一
- ADO第一次亲密接触 -- ADO开发实践之一
- ADO第一次亲密接触 -- ADO开发实践之一
- Centos接触 (二)
- (146)接触阴影
- 接触
- 亲密接触ASP+(1)
- 钩子初接触(一)
- 钩子初接触(二)
- 钩子初接触(三)
- 钩子初接触(四)
- auto_ptr的用法
- C#——小编浅谈如何在DataGridView控件中验证数据输入
- Observer设计模式——委托事件
- Net资源泄露(内存泄露,GDI泄露,handle 泄露等)的终极解决方案
- 2009年手机软件外包的经验和教训
- 协程三篇之一(协程初接触)
- C#经典面试之算法
- 建立IIS,局域网中的电脑访问我机器上的网页
- Entity SQL Language 二 基本执行方法、操作符、Select及Where
- test
- 发现并防止托管代码中出现内存泄漏
- volatile用法
- 页面静态化(JSP动态页面转静态化)
- 一些重要的计数器