zoukankan      html  css  js  c++  java
  • libevent学习七(bufferevent)

    1. 每个bufferevent 都拥有类型为struct evbuffer的input buffer和out buffer,分别供数据读取和数据写入使用。
    2.读取和写入数据是通过编写和设置对应的回调函数进行,而调用回调函数的时机则根据水位是否满足来的,水位又是可以设置的。默认情况下读的低水位是0,就是说libevent从底层读到大于0的数据到input buffer中,读回调函数就会调用,读回调函数读取input buffer的数据;同样默认的写水位也为0,就是说一旦output buffer中没有数据,就会调用写回调函数写入数据到output buffer,ouput buffer会自动由libevent传出到对端。
     
    3.bufferevent 除了有读写事件还有其他事件
        BEV_EVENT_READING:读过程中发生的事件
        BEV_EVENT_WRITING  :写过程中发生的事件
        BEV_EVENT_ERROR:操作过程中发生的事件
         BEV_EVENT_TIMEOUT:超时事件
         BEV_EVENT_EOF:到达文件末尾
         BEV_EVENT_CONNECTED:连接成功事件
     
     
     
    4.bufferevent的选项
        BEV_OPT_CLOSE_ON_FREE:释放bufferevent的时候释放掉底层的socket和底层的bufferevent
        BEV_OPT_THREADSAFE:自动上锁,多线程安全
        BEV_OPT_DEFER_CALLBACKS:延迟所有的回调函数(通常情况下,回调函数在满足条件的情况下是立即执行,但是同时执行的回调函数太多会可能会导致栈溢出,所以可以延迟回调函数的调用,使其成为事件循环的一部分,放入队列,等待其他的队列之前的回调函数被调用后在调用)
        BEV_OPT_UNLOCK_CALLBACKS :在执行用户提供的回调函数时解锁。
     
     
    5.接口
     
    //new一个基于socket的bufferevent,如果传入的socket fd为-1,则自动创建一个面向流的socket fd  
    struct bufferevent *bufferevent_socket_new(
        struct event_base *base,
        evutil_socket_t fd,
        enum bufferevent_options options);
     
     
    //如果bev指向的基于socket的bufferevent中的socket fd没有连接,则自动连接
    //没有连接之前是不可能从底层读写数据的,但是可以向output buffer写数据
    int bufferevent_socket_connect(struct bufferevent *bev,
        struct sockaddr *address, int addrlen);
     
    //监控到连接事件成功的事件后,需要主动写入一次,不然写回调函数不会触发,有点奇怪,但也可以理解
     
    //通过主机名建立连接
    int bufferevent_socket_connect_hostname(struct bufferevent *bev,
        struct evdns_base *dns_base, int family, const char *hostname,
        int port);
    int bufferevent_socket_get_dns_error(struct bufferevent *bev);
     
    //释放bufferevent
    void bufferevent_free(struct bufferevent *bev);
     
    //设置或获取回调函数
    //客户端的写入回调需要一个激活的过程,最好放在连接事件激活时来做
    typedef void (*bufferevent_data_cb)(struct bufferevent *bev, void *ctx);
    typedef void (*bufferevent_event_cb)(struct bufferevent *bev,
        short events, void *ctx);
    //如果事件指针设置为NULL则表示不启用该事件的处理方式
    void bufferevent_setcb(struct bufferevent *bufev,
        bufferevent_data_cb readcb, bufferevent_data_cb writecb,
        bufferevent_event_cb eventcb, void *cbarg);

    void bufferevent_getcb(struct bufferevent *bufev,
        bufferevent_data_cb *readcb_ptr,
        bufferevent_data_cb *writecb_ptr,
        bufferevent_event_cb *eventcb_ptr,
        void **cbarg_ptr);
     
     
    //打开或关闭事件处理过程( EV_READ, EV_WRITE, or EV_READ|EV_WRITE)
    //默认情况下新建的buffervent打开了写事件的处理过程,没有打开读的处理过程
    void bufferevent_enable(struct bufferevent *bufev, short events);
    void bufferevent_disable(struct bufferevent *bufev, short events);

    short bufferevent_get_enabled(struct bufferevent *bufev);
     
    //设置读写水位
    //events为( EV_READ,EV_WRITE的组合)
    void bufferevent_setwatermark(struct bufferevent *bufev, short events,
        size_t lowmark, size_t highmark);
     
    //获取读写evbuffer
    struct evbuffer *bufferevent_get_input(struct bufferevent *bufev);
    struct evbuffer *bufferevent_get_output(struct bufferevent *bufev);
     
    int bufferevent_write(struct bufferevent *bufev,
        const void *data, size_t size);
    int bufferevent_write_buffer(struct bufferevent *bufev,
        struct evbuffer *buf);
    size_t bufferevent_read(struct bufferevent *bufev, void *data, size_t size);
    int bufferevent_read_buffer(struct bufferevent *bufev,
        struct evbuffer *buf);
    //设置读写超时时间
    void bufferevent_set_timeouts(struct bufferevent *bufev,
        const struct timeval *timeout_read, const struct timeval *timeout_write);
    //强制写入或读取
    int bufferevent_flush(struct bufferevent *bufev,
        short iotype, enum bufferevent_flush_mode state);
     
    //锁和解锁
    void bufferevent_lock(struct bufferevent *bufev);
    void bufferevent_unlock(struct bufferevent *bufev);
     
    //其他接口
    int bufferevent_priority_set(struct bufferevent *bufev, int pri);
    int bufferevent_get_priority(struct bufferevent *bufev);
    int bufferevent_setfd(struct bufferevent *bufev, evutil_socket_t fd);
    evutil_socket_t bufferevent_getfd(struct bufferevent *bufev);
    struct event_base *bufferevent_get_base(struct bufferevent *bev);
    struct bufferevent *bufferevent_get_underlying(struct bufferevent *bufev);
     
     
     
  • 相关阅读:
    数仓备机DN重建:快速修复你的数仓DN单点故障
    深度学习分类任务常用评估指标
    云小课 | MRS基础入门之HDFS组件介绍
    华为云数据库GaussDB(for Cassandra)揭秘第二期:内存异常增长的排查经历
    为什么vacuum后表还是继续膨胀?
    Go 自定义日志库
    Go time包
    Go 文件操作
    Go 包相关
    【程序人生】跟小伙伴们聊聊我有趣的大学生活和我那两个好基友!
  • 原文地址:https://www.cnblogs.com/manziluo/p/5789643.html
Copyright © 2011-2022 走看看