libevent多线程使用bufferevent的那些事

原创 2016年11月09日 17:42:20
void do_accept(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *sa, int socklen, void *ctx)
{
    //不使用Nagle算法,选择立即发送数据而不是等待产生更多的数据然后再一次发送
    int optval = 1;
    setsockopt(fd, SOL_SOCKET, TCP_NODELAY, &optval, sizeof(optval));
    struct bufferevent * bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
    if (NULL == bev)
    {
        return 1;
    }
    bufferevent_setcb(bev, do_read, NULL, NULL, NULL);
    bufferevent_enable(bev, EV_READ);
}

在之前的《libevent使用event事件触发服务端实例》中,do_accept使用的event,这里使用了bufferevent,它们的区别:
1.bufferevent有自己的一套错误触发处理机制,可以在bufferevent_setcb设置错误回调函数,event没有
2.void do_read(struct bufferevent *bev, void *ctx);这是bufferevent的读事件回调函数格式
void do_read(evutil_socket_t fd, short ev, void *ctx);这是event的读事件回调函数格式
对于event回调传过去的参数是套接字,也就是说我们自己要在do_read中做recv操作,并存进数据缓冲中,对于bufferevent回调传过去的是bufferevent事件,看一下bufferevent的结构

struct bufferevent 
{
    struct event_base *ev_base;

    struct event ev_read;
    struct event ev_write;

    struct evbuffer *input;//接收数据缓冲
    struct evbuffer *output;//发送数据缓冲

    struct event_watermark wm_read;
    struct event_watermark wm_write;

    evbuffercb readcb;//读回调函数指针
    evbuffercb writecb;//写回调函数指针
    everrorcb errorcb;//错误回调函数指针
    void *cbarg;

    int timeout_read;   /* in seconds */
    int timeout_write;  /* in seconds */

    short enabled;  /* events that are currently enabled */
};

从结构可以看出来,bufferevent已经帮我们做了接收操作,并存在了缓冲input中,也就是说bufferevent相比较event是多了数据缓冲绑定,我们不需要考虑数据缓冲的事情了。当读事件触发,我们就调用bufferevent_read从input拿数据,一切都是那么轻松。既然bufferevent做了接收处理,当然也会通过recv返回值给我们做了错误回调。但是bufferevent不是线程安全的,具体表现:
1. 当你使用bufferevent发送或者接收数据的时候,同时发生断开情况,你要bufferevent_free,对同一个bufferevent出现的抢占会造成段错误,当然你可以打开libevent的锁机制解决这个问题,那也只是解决这个问题,又会带来另一个问题。现在发送或者接收和释放不冲突了,但是释放断开连接之后还发送数据的话,会造成死锁,锁死在bufferevent的锁里面。
2. 当你为新的连接创建bufferevent加入base里面的时候,另外有一个断开连接要从base里面拿出去,那么会造成对base的抢占段错误。当然event也会存在这个问题,打开libevent的锁是可以解决这个问题的。

对于第一种情况,解决的办法是有的,可以给bufferevent在包装一层,标记一个是否可用选项,释放的时候把标识设为不可用,发送和接收的时候先判断是否可用再操作来避免死锁,也就是说先打开了libevent的锁,然后包装一层之后为了这个标识又要再加一次锁。后来看了memcache源码,发现它没有使用bufferevent,只是使用了event来做触发,后面的所有操作都是围绕着套接字进行的,于是我也乖乖的使用基本套接字来进行所有的操作,毕竟关闭套接字的时候使用套接字发送接收不会崩溃,只是返回一个错误码给我们判断,毕竟关闭套接字之后再发送数据也不会死锁也是返回错误码给我们处理。

版权声明:本文为博主原创文章,如需转载请标明出处链接!否则追究法律责任! https://blog.csdn.net/peng314899581/article/details/53102720

libevent学习笔记【使用篇】——6a. Bufferevents高级话题

成对的bufferevent, 调用bufferevent_pair_new()会设置pair[0]和pair[1]为一对相互连接的bufferevent。 bufferevent_filter_ne...
  • Windeal
  • Windeal
  • 2016年10月19日 09:17
  • 1747

网络库libevent、libev、libuv对比

Libevent、libev、libuv三个网络库,都是c语言实现的异步事件库Asynchronousevent library)。 异步事件库本质上是提供异步事件通知(Asynchronous E...
  • lijinqi1987
  • lijinqi1987
  • 2017年05月05日 16:42
  • 15516

LibEvent中文帮助文档

LibEvent中文帮助文档:http://blog.csdn.net/zhouyongku LibEvent快速可移植非阻塞式网络编程...
  • zhouyongku
  • zhouyongku
  • 2016年12月02日 09:44
  • 6265

libevent的event处理框架剖析

前几次剖析了libevent的tail queue和evbuffer,今天来剖析一下它的事件处理框架。这个在剖析evbuffer之前已经大致走过几遍,但思路不是很清晰,是因为我没有用实例去测试even...
  • FreeeLinux
  • FreeeLinux
  • 2016年10月14日 13:33
  • 2677

libevent学习笔记 一、基础知识

1.   Libevent是什么? Libevent是一个轻量级的开源的高性能的网络库,被众多的开源项目使用,例如大名鼎鼎的memcached等。具有如下的显著的特点:事件驱动,轻量级(和ACE相比的...
  • majianfei1023
  • majianfei1023
  • 2015年06月14日 16:27
  • 38146

libevent实现https服务器

libevent实现https服务器 参考老外服务器代码: + https://github.com/ppelleti/https-example + 确保libevent在2....
  • gaoqingwuma
  • gaoqingwuma
  • 2017年08月30日 21:49
  • 2626

Windows下libevent C++封装类实现

题记windows平台下对于服务器高并发的网络模型选型中,使用libevent是个不错的选择。 本文针对libevent从服务端、客户端两个角度实现了封装类,真正做到,我们在使用封装类时候,只需要关...
  • wojiushiwo987
  • wojiushiwo987
  • 2016年12月11日 22:15
  • 4766

libevent高性能网络库源码分析——Reactor模式(二)

IO模型介绍 Reactor模式IO模型介绍在介绍libevent的Reactor模式之前,首先介绍下IO模型的: 1、 同步阻塞IO(Blocking IO): 即传统的IO模型。当用户进程向系...
  • wzgang123
  • wzgang123
  • 2016年04月18日 20:28
  • 1080

Libevent 编程- 定时器事件(timer event)

Libevent 编程- 定时器事件(timer event)本文介绍Libevent 三种事件之一的定时器事件。 该事件可以用来注册定时事件和周期性事件。Libevent 根据所有定时器事件的最小超...
  • u010090316
  • u010090316
  • 2017年04月26日 22:33
  • 1183

libevent入门

花了两天的时间在libevent上,想总结下,就以写简单tutorial的方式吧,貌似没有一篇简单的说明,让人马上就能上手用的。 首先给出官方文档吧: http://libevent.org ,...
  • funkri
  • funkri
  • 2013年07月17日 12:11
  • 39312
收藏助手
不良信息举报
您举报文章:libevent多线程使用bufferevent的那些事
举报原因:
原因补充:

(最多只允许输入30个字)