`
qiezi
  • 浏览: 497759 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

并发编程模型:Thread, Coroutine, Callback ...

阅读更多
先总结一下。

线程是最容易编写的并发方式,操作系统也提供了最好的支持;协程可以做到更强的并发能力,但需要实现调度器;回调是开销最小的,它本来不是特别为并发来设计的,它是通用的异步化操作的实现模型。

注意线程和协程本身也是使用异步来模拟同步,线程由操作系统来模拟,协程由用户级调度器模拟。模拟的过程是:发起事件请求、挂起当前执行过程(线程或协程)、响应事件请求、恢复挂起的执行过程。回调没有这么复杂,你需要自己把连续的执行过程分解成多步操作。

线程就不讨论了,用起来比较简单;协程之前简单研究了一下,切换开销比线程有很大改进,但还是有点大,用作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这样声明,所有调用它的方法都自动把这个属性向外传播。。。。。。

一种新的语言?
分享到:
评论
2 楼 qiezi 2008-04-08  
呵呵,糊涂了,我这里说的不就是Generator嘛。。
1 楼 qiezi 2008-04-08  
还有Generator,是否可以在D语言里实现空上来代替这么复杂的Callback?好像可以综合Coroutine逻辑连续性和Callback轻量级的优势。

相关推荐

    C++并发编程实战:示例源源码

    《C++并发编程实战》是一本深入探讨C++并发编程技术的书籍,其源码库名为Cpp-Concurrency-in-Action-master。并发编程是现代多核处理器环境下提高软件性能的关键技术,C++作为一门强大且灵活的编程语言,提供了丰富...

    Coroutine源码.zip

    协程的概念最早可以追溯到29世纪60年代,近年来由于其在处理异步I/O和高并发场景中的优势,尤其是在游戏开发、网络编程以及大数据处理等领域得到了广泛的应用。现在我们来深入探讨一下Coroutine的相关知识点。 首先...

    协程coroutine.h

    开源的c++协程实现,包含头文件即可使用详见https://github.com/tonbit/coroutine

    testco.zip_lua coroutine

    Lua中的协程通过`coroutine.create`来创建,`coroutine.resume`来启动或恢复,以及`coroutine.yield`来暂停当前协程并返回控制权。 1. **创建协程**: 使用`coroutine.create`函数,传入一个函数作为参数,生成一个...

    coroutine.tar.gz

    通过学习和理解"coroutine.tar.gz"中的实现,开发者可以掌握如何在AArch64平台上的Linux环境中高效地利用协程,这对于优化性能、减少资源消耗以及构建高性能并发应用具有重要意义。在实际开发中,这种技术特别适用于...

    la-coroutine.github.io:La Coroutine网站(第三名,法国里尔)

    La Coroutine网站 安装 首先,安装Ruby。 然后,安装Bundler和所有必需的插件: $ gem install bundler $ bundle install 用法 运行服务器: $ jekyll serve 打开浏览器,然后转到 执照 本网站是根据知识共享署名...

    coroutine2:Boost.Coroutine2

    boost.coroutine2 boost.coroutine2提供了用于通用子例程的模板,该模板允许多个入口点在某些位置挂起和恢复执行。 它保留了执行的本地状态,并允许多次输入子例程(如果必须在函数调用之间保持状态,则很有用)。 ...

    swoole-src-4.3.3.tar.gz

    同时,它引入了协程(Coroutine)概念,允许在单个进程中实现轻量级的并发,无需使用复杂的多线程或多进程编程。 9. **任务队列与工作进程**:Swoole支持自定义的工作进程模型,可以将耗时任务放入队列,由后台进程...

    Lua 基础教程(十六)协程.pdf

    - 接下来调用`coroutine.yield(value1+1, value2+1)`暂停协程,并将结果`4`和`3`返回给`coroutine.resume`。 - 然后继续执行`coroutine.resume(co, 12, 14)`,协程从上次暂停的地方恢复执行,并根据传入的新参数更新...

    PHP: Coroutine-based concurrency library for PHP.zip

    PHP: Coroutine-based concurrency library for PHP.zip

    协程式驱动框架Nepxion-Coroutine.zip

    Coroutine是基于Kilim/Promise JDeferred的协程式驱动框架,基于Apache Zookeeper的分布式规则存储和动态规则变更通知。 主要特性: 1. 基于微服务框架理念设计 2. 支持同步/异步调用 3. 支持串行/并行调用 4....

    edunetcatandroid:每个 edunet.cat 的应用程序 android

    8. **异步处理**:为了防止应用因长时间网络操作而阻塞UI线程,开发者可能使用了AsyncTask、Handler、IntentService或者现代的Coroutine进行后台任务处理。 9. **Material Design**:遵循Google的Material Design...

    coroutine_event.zip

    在libevent的基础上提供同步的接口,在获得异步效率的同时提供更方便的编程方式,即提供基于协程的并发模型。 green化 将IO对象进行改造以能和协程进行配合。在某种意义上,协程与线程的关系类似于线程与进程的关系...

    每日震精图项目源码

    5. **多线程处理**:为了不影响用户界面的流畅性,图片的下载和处理可能在后台线程进行,利用Android的AsyncTask或者现代的Coroutine库。 6. **权限管理**:考虑到Android系统的权限控制,应用可能需要请求读写存储...

    coroutinecc:基于ucontext实现的C++协程库

    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 简单的性能测试可以: ...

    开源项目-Freezerburn-go-coroutine.zip

    开源项目-Freezerburn-go-coroutine.zip是一个专注于Go语言协程(goroutine)的开源库,旨在简化并发编程。Go语言的协程是其强大的特性之一,它提供了轻量级线程的功能,允许开发者轻松地创建并运行大量并发任务,而...

    python-3.6.6-amd64.exe.zip

    Python 3.6.6是Python编程语言的一个稳定版本,专为AMD64(也称为x86_64)架构设计,适用于64位Windows操作系统。这个版本在2018年发布,包含了该语言的诸多改进和新特性。在Python 3.6系列中,有许多关键的更新和...

    slides:La Coroutine的演示幻灯片

    【标题】"slides:La Coroutine的演示幻灯片"揭示了这次讲解的主题是关于La Coroutine的,这是一种在JavaScript中实现的协程技术。协程是一种轻量级的并发执行模式,它允许程序在执行过程中暂停并保存状态,然后在...

    android考试源码

    7. **异步处理**:为避免UI卡顿,网络请求和文件下载通常会在后台线程进行,可以使用AsyncTask、IntentService或现代的LiveData、Coroutine进行异步操作。 8. **安全性**:考虑数据加密传输,防止数据在传输过程中...

Global site tag (gtag.js) - Google Analytics