为什么libevent怎么用的event

        前段时间阅读了libevent怎么用的源码讀毕,之前使用libevent怎么用时的一些疑问都已经豁然开朗了对于libevent怎么用源码的分析,可以移步查看如果是libevent怎么用的初学者,可以先阅读《》

        同一个文件描述符(fd)是可以多次调用event_new,产生不同的event的这些具有相同fd的event,回调函数和回调参数是可以不同的而且它们监听的事件也是鈳以不同(这可能是能关联多个event的原因吧)。

        如果多个event监听同一个fd的同一个事件比如可读事件。那么当这个fd变成可读后所有的监听该事件嘚event的回调函数都会被调用(即触发event)。没有监听该事件的event的回调函数不会被调用如果两个event监听同一个fd的不同事件,那么它们的触发相互独立

        通过libevent怎么用提供的evtimer_xxx宏函数,是无法把一个超时event设置成永久的于是有一些人就想在该超时event的超时回调函数中再次调用evtimer_add函数。这就有点像對不可靠的信号再次设置信号处理函数


        如果所在的系统支持MONOTONIC时间的话,那么没有影响如果不支持那么会有一些影响,即超时不那么准確关于MONOTONIC时间,可以参考可以用下面的代码测试你的系统是否支持MONOTONIC时间。

        如果不是频繁修改假如只修改一次,那么只会在修改后第一佽的超时可能(仅仅是可能)会不那么准确之后的超时又准确了(如果该event有EV_PERSIST选项的话)。为什么说“仅仅”、“不那么”呢因为这取决于你在libevent怎么用处于什么状态下  修改的系统时间。细节可以参考

        因为libevent怎么用内部实现信号event的原理就是对该信号设置一个信号捕抓函数(这也叫统一倳件源)。 对信号捕抓熟悉的读者应该明白信号捕抓函数只能有一个。你设置了另外一个那么将覆盖之前设置的。

这类多路IO复用函数的洺称不过在Windows平台上,返回是的”win32”一般情况下,在Windows平台上是选用select的至于什么时候选用IOCP,可以参考下一条

        注意:该函数只是确保libevent怎麼用线程安全,多线程的使用还是要靠自己写代码libevent怎么用里面的代码也没有使用多线程,它仅仅用到了锁和条件变量

        有。首先这三個东西的定制都应该放到程序的前面,确保放到其他任何libevent怎么用 API调用前其次,这个三者也是有顺序它们的顺序应该为:内存分配、日誌记录、线程锁。

        可以但为了安全,必须确保你的程序在一开始调用了evthread_use_pthreads函数如果主线程不是在调用其他event的回调函数,那么该event将马上被主线程添加到监听队列中和其他event一起等待事件的发生。至于主线程如何知晓次线程添加了event可以参考《》。

        如果读者试过仅仅用OS提供的系统网络API写非阻塞socket的发送代码的话那么一定被非阻塞气死了。你得考虑要发送的数据并没有在一次write调用中发送完此时,得找一个地方保存这些要发送的数据等到下次调用write时还要使用。但找一个地方是一个烦人的事情

        虽然bufferevent_write是非阻塞的,但它很好人当它返回后,他已經把用户要发送的数据都copy了一份保存在内部的缓冲区中。所以从bufferevent_write返回后就可以丢弃要发送的数据了,无需伤脑筋找地方保存这些数据

  bufferevent的可读事件是边沿触发的。也就是说如果客户端往服务器发了100字节的数据,而且客户端仅仅发送一次数据那么服务器触发可读事件後,就应该把这100字节都读出来(假设这100字节是一起到达的)不应该想着,这次回调只读4字节(比如是长度信息)然后等到下次回调再读取其他數据。因为客户端只发送一次数据所以不会再有下次回调了,即使bufferevent的缓冲区里面还有数据

  读事件的低水位比较容易理解,当bufferevent读缓冲区嘚数据到达这个低水位后用户设置的可读回调函数才会被调用。比如说用户设置了4字节的低水位,因为用户认为少于4字节都是不值得詓处理的当bufferevent的读缓冲区的数据量小于4字节时,并不会调用用户的可读回调函数当数据量大于等于4字节时,就会调用用户的可读回调函數

读取到bufferevent的读缓冲区中。客户端往服务器发送大量数据服务器会不断地把数据copy到bufferevent缓冲区中。此时TCP的滑动窗口协议就没有用了

        读事件嘚高水位此时就应运而生了,当bufferevent读缓冲区的数据量达到这个高水位后就不再从socket fd中读取数据了。此时socket fd的内核缓冲区会堆积大量数据,滑動窗口协议就起作用了当bufferevent的读缓冲区的数量少于高水位后,libevent怎么用又可以从socket fd的缓冲区读取数据停止读取、恢复读取这一系列操作都是甴libevent怎么用负责完成,用户完全不知情有的读者可能会想:既然已经监听了可读事件,那怎么做到socket 内核缓冲区既要保留数据又能避免无休止地触发可读事件。libevent怎么用的解决方法可以参考

        如果客户端往服务器发送了大量的数据,并且服务器是使用bufferevent的那么在bufferevent的读事件回调函数中,一般最多只能接收到4096个字节这个是libevent怎么用这个库本身代码所限制的。

fd的缓冲区里面有再多的数据用户在读事件回调函数中读取数据,是从bufferevent内部的缓冲区读取的所以最多只能读取4096字节。当然如果用户故意没有把这个4096字节读完那么下次可以读取超过4096字节。



}

德国人写的两个IO框架大家都说昰高性能的,但 从传统高性能服务器的观点分析能得出什么结论呢?

单线程非阻塞,确实比较好用!

相对于多线程单线程server没有线程切换以及加锁的开销,劣势是不能充分利用CPU的多核优势不过,这可以通过多个进程来解决

另外,这种模型编程也很简单因为简单,所以是编写高性能server的首选


}

用来做定时器即当达到一定时間后调用回调函数callback。用evtimer_add激活定时器比如:


bufferevent 内置了两个event(读/写)和相应的缓冲区,当有数据被读入(input)时readcb被调用,当output被输出完毕的时候writecb被调用。

当网络I/O出现错误如链接中断。超时或其它错误时errorcb被调用。比如 :BEV_EVENT_ERROR

假设bufferevent出现这个事件表示操作时错误发生。假设你是將bufferevent用作socket通信这个错误一般意味着socket连接断开。很多其它的错误信息须要调用EVUTIL_SOCKET_ERROR()

bufferevent由一个底层的传输port(如套接字)。一个读取缓冲区和一个写叺缓冲区组成与通常的事件在底层传输port已经就绪,能够读取或者写入的时候运行回调不同的是bufferevent在读取或者写入了足够量的数据之后调鼡用户提供的回调。

把数据写入一个bufferevent buffer中它被用来将数据写入文件描写叙述符,当数据变得能够写时会自己主动写入到描写叙述符中。

bufferevent_setcb()函数改动bufferevent的一个或者多个回调readcb、writecb和eventcb函数将分别在已经读取足够的数据、已经写入足够的数据,或者错误发生时被调用每一个回调函数嘚第一个參数都是发生了事件的bufferevent。最后一个參数都是调用bufferevent_setcb()时用户提供的cbarg參数:能够通过它向回调传递数据


 
分配和返回一个新的连接监听器对象,base參数是监听器用于监听连接的event_base即连接监听器使用event_base来得知什么时候在给定的监听套接字const struct sockaddr *sa(包括ip和port)上有新的TCP连接,新连接到达时监听器调用你给出的回调函数cb。

 
 
上面的两个Evconnlistener_new*() 函数都分配并返回一个新的连接监听器对象连接侦听器使用event_base获得通知,当在一个监听套接芓上有一个新的TCP连接
当一个新的连接到达时,它将调用你所提供的回调函数
在这两个函数中,侦听器使用一个event_base类型的base參数去侦听连接当一个新连接被接受时,回调函数Cb将被调用若回调cb是 NULL,监听器将被视为禁用直到设置回调Ptr指针将传递给回调。
Flags參数控制侦听器的行為
backlog參数控制着挂起连接的最大的数目,即不论什么时间网络堆栈应该同意等待中尚未接受的状态的数目假设backlog是负的。libevent怎么用 将尝试为backlog設置一个适当的值;假设它是零libevent怎么用 将假定您已经在套接字上调用 listen()。
这两个函数设置监听套接字的方式不同


 
 
evbuffer_remove() 函数将复制和删除前面嘚buf的datlen个字节到内存中的data中。假设少于datlen个字节可用函数将复制全部的字节。失败返回的值是-1否则返回复制的字节数。



}

我要回帖

更多关于 libevent怎么用 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信