全异步非阻塞svr需要一个好的易用功能强大的事件驱动器,接触过好几个这样的驱动器:比如 1,nginx的核心evt dirver,和http业务绑的非常紧,耦合非常重,基本很难抽取出来独用;
2,工作中用的最多的reactor,一个从java基本照搬到c++的事件驱动,只支持句柄读写+定时器
事件,比较简单,简单到有点粗略功能局限,工作中用了感觉还好,但是离理想驱动器非常远;
3,python的trwist框架是我感觉最强大,功能最丰富的驱动器,支持非常多种事件,且支持扩展
异步事件;另外包括了众多的上层应用(比如http,ftp,mail),研究了大概1周,确实很有趣;但感觉
过于复杂了,且是python写的,用python写这种异步svr现在不会去搞,以后应该会用这个实现一个框架;
日后再说;
4,libevent 感觉是离完美最近的异步驱动器了,支持句柄+定时器+信号事件;c写的,接口友好
稳定,且有大批应用;
但我还是最终实现了一个自己的驱动器,原因有三:
一来,libevent的事件支持有限,特别是我最喜欢的子进程调用(类似异步popen)事件不支
持(python中就有,非常好用);
二来,libevent的接口是比较友好,但我还是更倾向于在驱动器应和中层的应用有一定的交互和
耦合,比如时间,驱动器的timer肯定依赖于时间,而中层框架代码也肯定是需要时间的;我不想再在中层
应用中再去实现一遍时间功能;
三来,实现驱动器是一件很好玩的事情,强烈的欲望驱动我自己去实现一个,再造一次轮子,当然
这个轮子不是白手起家造的;是吸取了各个驱动器的优点,摒弃了缺点造的;
轮子造出来了,支持事件包括:
句柄读写,定时器,信号,子进程调用;
以下是接口api,接口没有 libevent 的接口清晰和易用,比如要注册一个fd读事件,需要先分配
事件,然后再注册;稍显繁琐,但更灵活,也更适合嫁接在这层驱动器上的框架代码;
另外,感觉对事件的包装上有些地方不合理的地方,如果不熟悉使用起来会感到一些迷惑...
接口设计要想清晰合理好用且正交无冗余确实不是一件易事,需要花费很大力气以及有丰富的经验
才行;
- yf_evt_driver_t* yf_evt_driver_create(yf_evt_driver_init_t* driver_init);
- void yf_evt_driver_destory(yf_evt_driver_t* driver);
- void yf_evt_driver_stop(yf_evt_driver_t* driver);
- void yf_evt_driver_start(yf_evt_driver_t* driver);
- yf_int_t yf_alloc_fd_evt(yf_evt_driver_t* driver, yf_fd_t fd
- , yf_fd_event_t** read, yf_fd_event_t** write, yf_log_t* log);
- yf_int_t yf_free_fd_evt(yf_fd_event_t* pread
- , yf_fd_event_t* pwrite);
- /*
- *oneshot event handler, means one register just call handle once...
- */
- yf_int_t yf_register_fd_evt(yf_fd_event_t* pevent, yf_time_t *time_out);
- /*
- *unregister used before event happen, means interupt fd poll
- */
- yf_int_t yf_unregister_fd_evt(yf_fd_event_t* pevent);
- #define FD_TIMER_NEW 0x01
- #define FD_TIMER_DEL 0x02
- /*
- * timer_new : fi org event have timer, then will cancel org first,
- * then add new with 0 passed time;
- * timer_del : cancell org
- */
- yf_int_t yf_fd_evt_timer_ctl(yf_fd_event_t* pevent, int mode, yf_time_t* time_out);
- yf_int_t yf_alloc_tm_evt(yf_evt_driver_t* driver, yf_tm_evt_t** tm_evt
- , yf_log_t* log);
- yf_int_t yf_free_tm_evt(yf_tm_evt_t* tm_evt);
- yf_int_t yf_register_tm_evt(yf_tm_evt_t* tm_evt, yf_time_t *time_out);
- yf_int_t yf_unregister_tm_evt(yf_tm_evt_t* tm_evt);
- /*
- * singal evt
- * in one processor, you can just register signo with one handler
- */
- yf_int_t yf_register_singal_evt(yf_evt_driver_t* driver
- , yf_sig_event_t* sig_evt, yf_log_t* log);
- yf_int_t yf_unregister_singal_evt(yf_evt_driver_t* driver
- , int signo);
- yf_int_t yf_alloc_proc_evt(yf_evt_driver_t* driver, yf_processor_event_t** proc_evt
- , yf_log_t* log);
- yf_int_t yf_free_proc_evt(yf_processor_event_t* proc_evt);
- yf_int_t yf_register_proc_evt(yf_processor_event_t* proc_evt, yf_time_t *time_out);
- yf_int_t yf_unregister_proc_evt(yf_processor_event_t* proc_evt);
- yf_process_t* yf_get_proc_by_evt(yf_processor_event_t* proc_evt);
具体代码我放 github 上了:
阅读(3240) | 评论(0) | 转发(1) |