先总结一下。
线程是最容易编写的并发方式,操作系统也提供了最好的支持;协程可以做到更强的并发能力,但需要实现调度器;回调是开销最小的,它本来不是特别为并发来设计的,它是通用的异步化操作的实现模型。
注意线程和协程本身也是使用异步来模拟同步,线程由操作系统来模拟,协程由用户级调度器模拟。模拟的过程是:发起事件请求、挂起当前执行过程(线程或协程)、响应事件请求、恢复挂起的执行过程。回调没有这么复杂,你需要自己把连续的执行过程分解成多步操作。
线程就不讨论了,用起来比较简单;协程之前简单研究了一下,切换开销比线程有很大改进,但还是有点大,用作IO事件调度还可以,粒度更小的操作就显得开销过大了,想象一下极端情况下每次调度只处理一字节;回调看起来是个不错的方式,但也有许多问题需要解决。
以上次的代码为例,这里简化一下:
void server_loop(int fd) {
while(true) {
register_read_event(fd);
wait_read_event();
int client = accept(fd);
close(client);
}
}
改成对应的callback方式,为了让代码更像是工具转过来的,我把上一篇的代码修改一下:
void server_loop(int fd) {
register_read_event(fd);
wait_read_event({
int clientfd = accept(fd);
close(clientfd);
server_loop(fd);
});
}
这里不打算讨论while循环的转换问题,虽然这也是个难题,但可以通过设置一个变量来避开。
看一下循环里面是如何转换的?只要把wait_read_event后面的代码放进一个closure就可以了。看起来很简单,如果可以通过宏或其它语言设施通知编译器把某行后面的代码构造一个代码块,的确是会简单一些,不过目前我还不知道有哪种语言可以这样。如果没有语言可以做到这样(或者你用的语言做不到),像上面一样手工构造这个代码块也是可以接受的,毕竟它提供了高性能的并发模式。
问题还没有彻底解决,构造这个代码块实际是撕裂了整个逻辑,想象一下,如果要把register_read_event/wait_read_event和accept封装起来,隐藏这个实现过程,结果要类似这样:
void server_loop(int fd) {
int client = register_read_event_AND_wait_AND_accept(fd);
close(client);
server_loop(fd);
}
问题来了,由于不是线程和协程模式,而是异步回调模式,这么写是不可能的,你只能再构造一个代码块:
void register_read_event_AND_wait_AND_accept(int fd, void delegate(int) dg) {
register_read_event(fd);
wait_read_event({
int client = accept(fd);
dg(client);
}
}
void server_loop(int fd) {
register_read_event_AND_wait_AND_accept(fd, (int client){
close(client);
server_loop(fd);
}
}
原以为把回调过程封装起来,以后直接调用就漂亮了,但结果却是每一次包装都没有减少它,你的逻辑必须做成closure传递进去,脱离不了这种不连贯的方式。
或许让编译器来转换?还是写成这样:
void server_loop(int fd) {
int client = register_read_event_AND_wait_AND_accept(fd);
close(client);
server_loop(fd);
}
它自动转成:
void server_loop(int fd) {
register_read_event_AND_wait_AND_accept(fd, (int client){
close(client);
server_loop(fd);
}
}
如果修改编译器或许能让它做到,把register_read_event_AND_wait_AND_accept声明成asynchronized,它就自动把该调用以及之后的代码进行转换。或者只要把wait_read_event这样声明,所有调用它的方法都自动把这个属性向外传播。。。。。。
一种新的语言?
分享到:
相关推荐
开源的c++协程实现,包含头文件即可使用详见https://github.com/tonbit/coroutine
Coroutine源码
La Coroutine网站 安装 首先,安装Ruby。 然后,安装Bundler和所有必需的插件: $ gem install bundler $ bundle install 用法 运行服务器: $ jekyll serve 打开浏览器,然后转到 执照 本网站是根据知识共享署名...
boost.coroutine2 boost.coroutine2提供了用于通用子例程的模板,该模板允许多个入口点在某些位置挂起和恢复执行。 它保留了执行的本地状态,并允许多次输入子例程(如果必须在函数调用之间保持状态,则很有用)。 ...
协程切换示例及上下文保存与恢复,下载于:https://github.com/hymanyx/coroutine
Coroutine是基于Kilim/Promise JDeferred的协程式驱动框架,基于Apache Zookeeper的分布式规则存储和动态规则变更通知。 主要特性: 1. 基于微服务框架理念设计 2. 支持同步/异步调用 3. 支持串行/并行调用 4....
在libevent的基础上提供同步的接口,在获得异步效率的同时提供更方便的编程方式,即提供基于协程的并发模型。 green化 将IO对象进行改造以能和协程进行配合。在某种意义上,协程与线程的关系类似于线程与进程的关系...
coroutine 0 : 0 coroutine 1 : 200 coroutine 0 : 1 coroutine 1 : 201 coroutine 0 : 2 coroutine 1 : 202 coroutine 0 : 3 coroutine 1 : 203 coroutine 0 : 4 coroutine 1 : 204 main end 简单的性能测试可以: ...
基于AArch64平台,Linux内核任务切换的实现机制,应用层的简单协程实现。详见相关博客的帖子。
安卓 Kotlin Coroutine协程 使用方式代码举例: 包含GlobalScope 、CoroutineScope 详细使用代码举例,相关介绍文章,可参考: https://xiaxl.blog.csdn.net/article/details/123383727
您可以先使用coroutine_open打开一个计划,然后在该计划中创建coroutine。 您应该在调用coroutine_open的线程中调用coroutine_resume,并且不能在同一调度中的协程中调用它。 相同计划中的协程共享堆栈,因此您...
我们通常所说的协程Coroutine其实是corporateroutine的缩写,直接翻译为协同的例程,一般我们都简称为协程。 在linux系统中,线程就是轻量级的进程,而我们通常也把协程称为轻量级的线程即微线程。 进程和协程 下面...
Unity的协程技术,有可以用的朋友不妨看一下!如果本书不好不喜勿喷
今天安装gevent时出现 ERROR: Command errored out with exit status 1,后面还有一堆错误,好像是说“文件”、setup啊之类的,我在网上花了两小时查了很多...Gevent: a coroutine-based networking library based o
开源项目-Freezerburn-go-coroutine.zip,一个简单的协同程序库
NULL 博文链接:https://dsqiu.iteye.com/blog/2049743
协程 Rust的协程库[ dependencies ]coroutine = " 0.8 "用法协程的基本用法extern crate coroutine;use std :: usize ;use coroutine :: asymmetric :: Coroutine;fn main () { let coro: Coroutine < i32> = ...
NULL 博文链接:https://eleopard.iteye.com/blog/1750384
A asymmetric coroutine library for C..zip
:: NEW Added Coroutine support to actions. :: Build behaviors in an intuitive Graph View. :: Drag-and-Drop Actions - no syntax errors! :: Save time with Copy/Paste and Templates. :: Access scripts...