个人笔记(4)

最近几天一直在看libevent的源代码。

看的方法是:

  ①网络上一些大牛的博客资料

  ②libevent源代码(版本:Libevent 2.0.16-stable)

  ③libevent例子程序

  ④libevent相关文档

特别推荐的学习资料是张亮大牛的Blog:http://blog.csdn.net/sparkliang/article/category/660506

跟着这个资料,再动手调一下库中自带的例子程序,你很容易就能够了解libevent的事件处理流程。

下面是一个对例子程序hello-world.c写的一个client程序:

 1 /* Don't actually copy this code: it is a poor way to implement an
 2    HTTP client.  Have a look at evhttp instead.
 3 */
 4 #include <event2/bufferevent.h>
 5 #include <event2/buffer.h>
 6 #include <event2/event.h>
 7 #include <sys/socket.h>
 8 #include <string.h>
 9 #include <stdio.h>
10 
11 void readcb(struct bufferevent *bev, void *ptr)
12 {
13     char buf[1024];
14     int n;
15     struct evbuffer *input = bufferevent_get_input(bev);
16     while ((n = evbuffer_remove(input, buf, sizeof(buf))) > 0) 
17     {
18         fwrite(buf, 1, n, stdout);
19     }
20 }
21 
22 void eventcb(struct bufferevent *bev, short events, void *ptr)
23 {
24     if (events & BEV_EVENT_CONNECTED) 
25     {
26         printf("Connect okay.\n");
27     } 
28     else if (events & (BEV_EVENT_ERROR|BEV_EVENT_EOF)) 
29     {
30         struct event_base *base = (struct event_base *)ptr;
31         if (events & BEV_EVENT_ERROR) 
32         {
33             printf("BEV_EVENT_ERROR\n");
34         }
35         printf("Closing\n");
36         bufferevent_free(bev);
37         event_base_loopexit(base, NULL);
38     }
39 }
40 
41 int main(int argc, char **argv)
42 {
43     struct event_base *base;
44     struct bufferevent *bev;
45     struct sockaddr_in sin;
46 
47     base = event_base_new();
48     
49     memset(&sin, 0, sizeof(sin));
50     sin.sin_family = AF_INET;
51     sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */
52     sin.sin_port = htons(9995);
53 
54     bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
55     //set callback function
56     bufferevent_setcb(bev, readcb, NULL, eventcb, base);
57     //enable read event
58     bufferevent_enable(bev, EV_READ);
59     //disabel write event
60     bufferevent_disable(bev, EV_WRITE);
61     
62     if (bufferevent_socket_connect(bev,(struct sockaddr *)&sin, sizeof(sin)) < 0) 
63     {
64         bufferevent_free(bev);
65         return -1;
66     }
67     
68     event_base_dispatch(base);
69     
70     return 0;
71 }

通过这个例子可以知道,libevent在处理事件的大体过程是:

①通过event_base_new()创建一个event_base实例

②通过event_add()(这里使用的是bufferevent_socket_new())将一个event绑定到一个base

③设置相应的I/O事件回调函数(读写事件),信号事件回调函数,超时事件回调函数等参数

④调用event_base_dispatch()进入事件主循环,其间触发什么事件,就调用相应的事件回调函数进行处理

其他:

①libevent用到的基本数据结构主要是双向链表和最小堆,用双向链表存储事件,用最小堆处理超时

②libevent根据系统选择处理异步IO的方法,可以通过相关API查询系统支持的方法,例如:

 1 #include <event2/event.h>
 2 #include <stdio.h>
 3 
 4 int main(int argc, char *argv[])
 5 {
 6     int i;
 7     const char **methods = event_get_supported_methods();
 8     printf("Starting Libevent %s.  Available methods are:\n", event_get_version());
 9     
10     for (i=0; methods[i] != NULL; ++i) 
11     {
12         printf("    %s\n", methods[i]);
13     }
14     
15     struct event_base *base;
16     enum event_method_feature f;
17 
18     base = event_base_new();
19     if (!base) 
20     {
21         puts("Couldn't get an event_base!\n");
22     } 
23     else 
24     {
25         printf("Using Libevent with backend method %s.", event_base_get_method(base));
26         f = (enum event_method_feature)event_base_get_features(base);
27         if ((f & EV_FEATURE_ET))
28             printf("  Edge-triggered events are supported.\n");
29         if ((f & EV_FEATURE_O1))
30             printf("  O(1) event notification is supported.\n");
31         if ((f & EV_FEATURE_FDS))
32             printf("  All FD types are supported.\n");
33         puts("");
34     }
35     
36     event_base_free(base);
37     
38     return 0;
39 }

 

参考资料:

1、张亮《libevent源码深度剖析系列》:http://blog.csdn.net/sparkliang/article/category/660506

2、libevent官方文档:http://www.wangafu.net/~nickm/libevent-book/

3、《libevent源码浅析:事件处理框架》:

  http://godorz.info/2011/02/the-annotated-libevent-sources-about-event-handling-framework/

4、《libevent源码分析:min_heap带来的超时机制》:http://www.cppblog.com/kevinlynx/archive/2008/07/18/56511.html

 

 

 

posted @ 2013-03-04 16:16  么幺  阅读(301)  评论(0编辑  收藏  举报