您的位置:首页 > 其它

CERL2 系列1: Hello,CERL2!纤程!

2010-01-08 01:38 113 查看
CERL2 经过一段时间的发展,已经稳定下来,是时候揭开它的面纱了。和 CERL2 最初设想并不一样,CERL2 最终没有成为一种语言,它在 CERL 上进行了编程模型的演化,并且形成了多个子库。最主要的两个子库为 async 和 venus。最底层的是 async,它需要针对不同的平台进行包装,以此形成一个网络层。你可以 拿 async 和 boost asio 类比,两者确实是类似的东西,只是编程理念不同。而 venus 是基于 async 之上的,一个平台无关的网络编程模型,这个模型是基于 Erlang Style Concurrency 观念的一个变种,它试图消除 Erlang 编程模型的一些缺陷



本文是 CERL2 系列介绍的第1篇。按照惯例,我们写一个 Hello CERL2。代码看起来是这样的:



#include <async/Application.h>
void cerl_callback hello(LPVOID lpParam)
{
    cerl::FiberParam p(lpParam);
    printf("Hello, CERL2!/n");
    p.service->quit();
}
int main()
{
    cerl::Application app;
    app.run(hello);
}


在 CERL2 中,我们一个最基础的概念是 Fiber(纤程)。它类似erlang中的进程(Process),是一个轻量级的执行体。上面 hello 函数就是一个纤程

。它打印 Hello, CERL2! 后,退出整个程序。请注意 p.service->quit() 这句并不是退出纤程,而是退出 app.run(hello) 内部的循环。



要启动多个纤程,用 startFiber 函数:



#include <async/Application.h>
void cerl_callback hello(LPVOID lpParam)
{
    cerl::FiberParam p(lpParam);
    printf("Hello, CERL2!/n");
}
void cerl_callback test(LPVOID lpParam)
{
    cerl::FiberParam p(lpParam);
    cerl::startFiber(p.self, hello);
    cerl::startFiber(p.self, hello);
    p.service->quit();
}
int main()
{
    cerl::Application app;
    app.run(test);
}


这个程序先启动了test纤程,然后test在运行中启动了2个hello纤程。程序运行结果是打印两句 Hello,CERL2!。



至此,Fiber 的基本用法已经会了。很简单吧?



那么 cerl::FiberParam 类用于干什么的?这个类从角色来说只是辅助类。但是又非常关键。其功用在于:



获取纤程相关信息。主要是:

* cerl::IoService* service;
* cerl::Fiber* self;
* LPVOID val; // startFiber 传入的额外参数。

析构时自动调用 service->exitFiber(self); 退出当前纤程。



这里又带了了新概念:IoService。这个我们下回接着聊。对于上面介绍的内容,可能你最大的一个疑问是为什么不把 cerl::FiberParam 这个类隐藏起来。这当然是可能的,无非就是纤程的原型改为:



void cerl_callback FiberProc(cerl::Fiber* self, LPVOID val);



其中 cerl::IoService 是可以通过 self 取到的,所以可以不传入。



我的回答是,个人习惯而已。async 是底层库,我的习惯是包装得越薄越好。在这个 startFiber 之上,你完全可以自己写一个 spawn 函数,将 cerl::FiberParam 这个细节隐藏。这个包装手法很简单,我就不在这里罗嗦了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: