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

结合Coroutine和Callback

阅读更多
Coroutine切换成本相对还是比较高的,把一个并发程序改成Coroutine实现性能上可能有比较大的损失。Coroutine切换主要是大量寄存器压栈和弹栈,栈切换也会影响到cache。目前C/C++大量使用的是回调方式,比如win32窗口编程、libevent等,优点是高效,函数调用成本是很低的,也没有栈切换,缺点是不如Coroutine这样连贯。有没有方法让它具有两者的优点呢?有Coroutine连贯的过程,也有Callback的高效?还是考虑这个简单的例子:

(本文代码使用D语法,但并没有编译测试)

void client_loop(int fd) {
  while(true) {
    register_read_event(fd);
    wait_read_event();
    char buf[1024];
    int ret = recv(fd, buf.ptr, buf.length, 0);
    if (ret <= 0) {
       writefln("recv fail");
       remove_events(fd);
       close(fd);
       break;
    }
    writefln("received:", buf[0..ret]);
  }
}

void server_loop(int fd) {
  while(true) {
    register_read_event(fd);
    wait_read_event();
    int client = accept(fd);
    spawn(client_loop, client);
  }
}


假定它是以Coroutine方式来实现的,Coroutine这样来实现也是很简单的。对应的Callback是什么形式呢?我假想了一个:

void client_loop(int fd) {
    register_read_event(fd)
      .on_event({
        char buf[1024];
        int ret = recv(fd, buf.ptr, buf.length, 0);
        if (ret <= 0) {
           writefln("recv fail");
           remove_events(fd);
           close(fd);
        }
        else {
          writefln("received:", buf[0..ret]);
          client_loop(fd);
        }
      });
}

void server_loop(int fd) {
  register_read_event(fd)
    .on_event({
      int clientfd = accept(fd);
      client_loop(clientfd);
      server_loop(fd);
    });
}

注意这并不是递归,因为server_loop和client_loop是立即返回的,里面那个代码块只是closure。

这段代码可读性明显不如上面好,你必须时刻思考需要在哪里创建一个closure,只因为并发时需要切换,当然下面这个实现效率会好得多。有没有办法用Coroutine这种连贯的写法达到Callback这样的效率呢?这是最近想要研究的问题。。
12
3
分享到:
评论
4 楼 qiezi 2008-04-01  
main里的ev没用的,测试时忘了删掉。。

Event对象是由gc来管理的,所以我需要在EventManager里面加个引用防止它在使用过程中被干掉。
3 楼 sleets 2008-03-31  
感觉闭包把可以省下很多函数或变量名,另外逻辑上也比较紧凑了。
2 楼 sleets 2008-03-31  
test2.d里动态生成的Event什么时候析构啊?

另外不明白在main里创建的Event ev是做什么用的。。
1 楼 qiezi 2008-03-31  
上面这段callback方式的D语言代码我用libevent简单测试过了,还没发现问题。

有兴趣可以看看代码:

http://jies.googlecode.com/svn/trunk/libeventd

里面的test2.d是个简单的并发echo服务器,需要DMD 2.0x以上版本,具体哪个版本我忘了,至少要支持closure的。

test2.d:

void server_loop(EventManager em, Socket sock) {
	em.add_read_event(sock.handle(), EVENT_MASK.PERSIST)
		.on_event((Event event){
			writefln("do accept");
			Socket client = sock.accept();
			em.add_read_event(client.handle(), EVENT_MASK.PERSIST, 3000)
				.on_event((Event event){
					writefln("do recv");
					char[] buf;
					buf.length = 1024;
					int ret = client.receive(buf);
					if (ret <= 0) {
						writefln("recv fail");
						em.remove_event(event);
						client.close();
					}
					buf.length = ret;
					em.add_write_event(client.handle())
						.on_event((Event event){
							writefln("do send");
							int ret = client.send(buf);
							if (ret <= 0) {
								writefln("send fail");
								em.remove_event(event);
								client.close();
							}
						});
				});
		});
}

相关推荐

    易语言coroutine_test源码,易语言协同程序接口模块

    易语言协同程序接口模块源码,协同程序接口模块,子程序1,yield_sleep,coroutine_run,coroutine_init,init_check,coroutine_create,coroutine_callback,coroutine_destroy,coroutine_resume,coroutine_status,...

    Coroutine源码.zip

    首先,`Coroutine.cpp`和`Coroutine.h`这两个文件分别代表了C++中的源代码文件和头文件。`Coroutine.cpp`包含了实现协程功能的具体代码,而`Coroutine.h`则可能定义了相关的类、函数接口或者宏定义,供其他源文件...

    协程Coroutine和Kilim

    结合提供的`Promise`和`Fiber`机制,使得编写并发代码更加简单、可控。对于需要处理大量并发请求的系统,如网络服务器或高并发的微服务,Kilim是一个值得考虑的选择。通过深入学习和实践Kilim,开发者可以更好地理解...

    Coroutine_Source_

    Coroutine_Source_Test

    基于linux cpp实现的协程库coroutine

    本篇文章将深入探讨基于Linux环境下使用C++实现的协程库coroutine,并结合网络编程的应用场景,提供详细的知识点讲解。 首先,我们理解一下协程的基本概念。协程可以看作是用户级别的线程,它们可以在执行过程中...

    Python coroutine

    David Beazley作的关于Python并发coroutine的介绍slides

    coroutine_event.zip

    将IO对象进行改造以能和协程进行配合。在某种意义上,协程与线程的关系类似于线程与进程的关系,你可以将协程理解成用户态线程。目前的IO操作都可能会导致整个线程的挂起,但是我们只希望挂起当前执行的协程,因此...

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

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

    Unity3D中如何终止协同程序Coroutine1

    Unity3D设计协同程序与`MonoBehaviour`结合,是为了方便管理和避免线程混乱。在多开发人员项目中,直接通过方法名来启动和停止协同程序可能引发错误。因此,推荐的做法是将协同程序封装在独立的类或脚本中,通过...

    Lua_Coroutine

    Lua Coroutine,协程详解,lua 基本础,The Programming Language Lua

    协程coroutine.h

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

    testco.zip_lua coroutine

    4. **协程状态**: `coroutine.status`可以查询协程的状态,包括`running`(正在运行)、`suspended`(已暂停)、`normal`(正常,未启动或已结束)和`dead`(已结束)。 **Linux的`makecontext`函数** `...

    C++20 Coroutine PPT

    通过使用Coroutine,开发者可以避免传统异步编程中的回调地狱和繁琐的管理,提高代码的可读性和维护性。 首先,让我们回顾一下传统的同步和异步程序。在同步程序中,函数会顺序执行,直到完成。例如,`doSomething...

    gfirefly firefly-gevent是firefly的gevent版本基于coroutine的python网络开发框架

    协程是一种并发模型,但不同于thread和callback,它的所有task都是可以在一个线程里面执行,然后可以通过在一个task里面主动放弃执行来切换到另一个task执行,它的调度是程序级的,不像thread是系统级的调度。...

    Unity协程(Coroutine)原理深入剖析再续

    Unity中的协程(Coroutine)是游戏开发中一种重要的编程机制,它允许开发者在不阻塞主线程的情况下执行异步操作,比如实现动画过渡、延迟执行、持续性逻辑更新等。在Unity引擎中,协程是通过`IEnumerator`接口实现的...

    Unity3D技术之Unity3D中的协程(Coroutine)详解.docx

    本文将详细介绍 Unity3D 中的协程(Coroutine)技术,包括为什么需要协程、协程的定义和工作原理、如何使用协程等方面的知识点。 一、为什么需要协程 在游戏中,有许多过程需要花费多个逻辑帧去计算。如果我们不...

    安卓Kotlin Coroutine协程使用案例代码

    安卓 Kotlin Coroutine协程 使用方式代码举例: 包含GlobalScope 、CoroutineScope 详细使用代码举例,相关介绍文章,可参考: https://xiaxl.blog.csdn.net/article/details/123383727

    LUA - coroutine

    The concept of a coroutine is one of the oldest proposals for a general control abstraction. It is attributed to Conway [Conway, 1963], who described coroutines as “subroutines who act as the master ...

    C++ Coroutine简单学习教程

    在C++里,一个函数如果其函数体实现中包含co_await、co_yield、co_return中任何一个关键字,那么这个函数就是一个coroutine。其中: co_await:挂起当前的coroutine co_return:从当前coroutine返回一个结果 co_...

Global site tag (gtag.js) - Google Analytics