﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-mysileng-随笔分类-LIBEVENT</title><link>http://www.cppblog.com/mysileng/category/20374.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 25 Jun 2013 03:33:08 GMT</lastBuildDate><pubDate>Tue, 25 Jun 2013 03:33:08 GMT</pubDate><ttl>60</ttl><item><title>翻译：libevent参考手册第九章：连接监听器：接受TCP连接 (十一) (转)</title><link>http://www.cppblog.com/mysileng/archive/2013/02/07/197763.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Thu, 07 Feb 2013 02:48:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/02/07/197763.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/197763.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/02/07/197763.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/197763.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/197763.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 译自http://www.wangafu.net/~nickm/libevent-book/Ref8_listener.htmlevconnlistener机制提供了监听和接受TCP连接的方法。本章的所有函数和类型都在event2/listener.h中声明，除非特别说明，它们都在2.0.2-alpha版本中首次出现。1&nbsp;创建和释放evconnlistener接口Code highlig...&nbsp;&nbsp;<a href='http://www.cppblog.com/mysileng/archive/2013/02/07/197763.html'>阅读全文</a><img src ="http://www.cppblog.com/mysileng/aggbug/197763.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-02-07 10:48 <a href="http://www.cppblog.com/mysileng/archive/2013/02/07/197763.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：libevent参考手册第八章：evbuffer：缓冲IO实用功能 (十) （转）</title><link>http://www.cppblog.com/mysileng/archive/2013/02/05/197748.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Tue, 05 Feb 2013 10:52:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/02/05/197748.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/197748.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/02/05/197748.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/197748.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/197748.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 译自http://www.wangafu.net/~nickm/libevent-book/Ref7_evbuffer.htmllibevent的evbuffer实现了为向后面添加数据和从前面移除数据而优化的字节队列。evbuffer用于处理缓冲网络IO的&#8220;缓冲&#8221;部分。它不提供调度IO或者当IO就绪时触发IO的功能：这是bufferevent的工作。除非特别说明，本章描述的...&nbsp;&nbsp;<a href='http://www.cppblog.com/mysileng/archive/2013/02/05/197748.html'>阅读全文</a><img src ="http://www.cppblog.com/mysileng/aggbug/197748.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-02-05 18:52 <a href="http://www.cppblog.com/mysileng/archive/2013/02/05/197748.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：libevent参考手册第七章：Bufferevent：高级话题 (九) （转）</title><link>http://www.cppblog.com/mysileng/archive/2013/02/05/197746.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Tue, 05 Feb 2013 09:39:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/02/05/197746.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/197746.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/02/05/197746.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/197746.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/197746.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 译自http://www.wangafu.net/~nickm/libevent-book/Ref6a_advanced_bufferevents.html&nbsp;本章描述bufferevent的一些对通常使用不必要的高级特征。如果只想学习如何使用bufferevent，可以跳过这一章，直接阅读下一章。1&nbsp;成对的bufferevent有时候网络程序需要与自身通信。比如说，通过某些协议...&nbsp;&nbsp;<a href='http://www.cppblog.com/mysileng/archive/2013/02/05/197746.html'>阅读全文</a><img src ="http://www.cppblog.com/mysileng/aggbug/197746.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-02-05 17:39 <a href="http://www.cppblog.com/mysileng/archive/2013/02/05/197746.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：libevent参考手册第六章：bufferevent：概念和入门 (八) （转）</title><link>http://www.cppblog.com/mysileng/archive/2013/02/05/197740.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Tue, 05 Feb 2013 06:38:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/02/05/197740.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/197740.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/02/05/197740.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/197740.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/197740.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 很多时候，除了响应事件之外，应用还希望做一定的数据缓冲。比如说，写入数据的时候，通常的运行模式是：l&nbsp;决定要向连接写入一些数据，把数据放入到缓冲区中l&nbsp;等待连接可以写入l&nbsp;写入尽量多的数据l&nbsp;记住写入了多少数据，如果还有更多数据要写入，等待连接再次可以写入这种缓冲IO模式很通用，libevent为此提供了一种通用机制，即bufferevent。buffere...&nbsp;&nbsp;<a href='http://www.cppblog.com/mysileng/archive/2013/02/05/197740.html'>阅读全文</a><img src ="http://www.cppblog.com/mysileng/aggbug/197740.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-02-05 14:38 <a href="http://www.cppblog.com/mysileng/archive/2013/02/05/197740.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：libevent参考手册第五章：辅助类型和函数 (七) (转)</title><link>http://www.cppblog.com/mysileng/archive/2013/02/05/197739.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Tue, 05 Feb 2013 06:19:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/02/05/197739.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/197739.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/02/05/197739.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/197739.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/197739.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 译自http://www.wangafu.net/~nickm/libevent-book/Ref5_evutil.html&nbsp;&nbsp; &nbsp;转自：http://blog.sina.com.cn/s/blog_56dee71a0100qo9t.html&lt;event2/util.h&gt;定义了很多在实现可移植应用时有用的函数，libevent内部也使用这些类型和函数。1&...&nbsp;&nbsp;<a href='http://www.cppblog.com/mysileng/archive/2013/02/05/197739.html'>阅读全文</a><img src ="http://www.cppblog.com/mysileng/aggbug/197739.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-02-05 14:19 <a href="http://www.cppblog.com/mysileng/archive/2013/02/05/197739.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：libevent参考手册第四章：与事件一起工作 (六) （转）</title><link>http://www.cppblog.com/mysileng/archive/2013/02/04/197720.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Mon, 04 Feb 2013 09:59:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/02/04/197720.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/197720.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/02/04/197720.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/197720.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/197720.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 译自http://www.wangafu.net/~nickm/libevent-book/Ref4_event.html转自:http://blog.sina.com.cn/s/blog_56dee71a0100qi0y.htmllibevent的基本操作单元是事件。每个事件代表一组条件的集合，这些条件包括：v&nbsp;文件描述符已经就绪，可以读取或者写入v&nbsp;文件描述符变为就绪状态，...&nbsp;&nbsp;<a href='http://www.cppblog.com/mysileng/archive/2013/02/04/197720.html'>阅读全文</a><img src ="http://www.cppblog.com/mysileng/aggbug/197720.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-02-04 17:59 <a href="http://www.cppblog.com/mysileng/archive/2013/02/04/197720.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：Libevent参考手册第三章：与事件循环一起工作 (五) （转）</title><link>http://www.cppblog.com/mysileng/archive/2013/02/04/197719.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Mon, 04 Feb 2013 09:36:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/02/04/197719.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/197719.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/02/04/197719.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/197719.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/197719.html</trackback:ping><description><![CDATA[<div><span style="font-family: simsun; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; color: #464646; ">译自<a href="http://www.wangafu.net/~nickm/libevent-book/Ref3_eventloop.html" style="text-decoration: none; color: #41646f; ">http://www.wangafu.net/~nickm/libevent-book/Ref3_eventloop.html<br /></a></span><span class="Apple-style-span" style="font-family: 新宋体; color: #000000; ">转自:<a href="http://blog.sina.com.cn/s/blog_56dee71a0100qe76.html"><span style="color: #000000; ">http://blog.sina.com.cn/s/blog_56dee71a0100qe76.html</span></a></span><div><h1 style="color: #464646; "><span style="word-wrap: normal; word-break: normal; line-height: 28px; font-family: 新宋体; color: #0000ff; font-size: 14pt; font-weight: bold; ">1&nbsp;<wbr>运行循环</span></h1><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; color: #464646; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">一旦有了一个已经注册了某些事件的event_base（关于如何创建和注册事件请看下一节），就需要让libevent等待事件并且通知事件的发生。</span></p><h2><span style="word-wrap: normal; word-break: normal; line-height: 28px; font-family: 新宋体; font-size: 14pt; font-weight: bold; "><font class="Apple-style-span" color="#0000FF">接口</font><br /><div style="background-color: #eeeeee; font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; color: #0000ff; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;EVLOOP_ONCE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x01</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;EVLOOP_NONBLOCK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x02</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;EVLOOP_NO_EXIT_ON_EMPTY&nbsp;0x04</span><span style="color: #000000; "><br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;event_base_loop(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;event_base&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">base</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;flags);</span></div><div style="color: #0000ff; "><span style="color: #464646; font-family: simsun; font-size: 14px; line-height: 21px; font-weight: normal; "><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">默认情况下，event_base_loop（）函数运行event_base直到其中没有已经注册的事件为止。执行循环的时候，函数重复地检查是否有任何已经注册的事件被触发（比如说，读事件的文件描述符已经就绪，可以读取了；或者超时事件的超时时间即将到达）。如果有事件被触发，函数标记被触发的事件为&#8220;激活的&#8221;，并且执行这些事件。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">在flags参数中设置一个或者多个标志就可以改变event_base_loop（）的行为。如果设置了EVLOOP_ONCE，循环将等待某些事件成为激活的，执行激活的事件直到没有更多的事件可以执行，然会返回。如果设置了EVLOOP_NONBLOCK，循环不会等待事件被触发：循环将仅仅检测是否有事件已经就绪，可以立即触发，如果有，则执行事件的回调。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">完成工作后，如果正常退出，event_base_loop（）返回0；如果因为后端中的某些未处理错误而退出，则返回-1。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">为帮助理解，这里给出event_base_loop（）的算法概要：</span></p><h2><span style="word-wrap: normal; word-break: normal; line-height: 28px; font-family: 新宋体; color: #0000ff; font-size: 14pt; font-weight: bold; ">伪代码</span></h2></span></div><div style="background-color: #eeeeee; font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; color: #0000ff; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">while</span><span style="color: #000000; ">&nbsp;(any&nbsp;events&nbsp;are&nbsp;registered&nbsp;with&nbsp;the&nbsp;loop,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;or&nbsp;EVLOOP_NO_EXIT_ON_EMPTY&nbsp;was&nbsp;</span><span style="color: #0000FF; ">set</span><span style="color: #000000; ">)&nbsp;{<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(EVLOOP_NONBLOCK&nbsp;was&nbsp;</span><span style="color: #0000FF; ">set</span><span style="color: #000000; ">,&nbsp;or&nbsp;any&nbsp;events&nbsp;are&nbsp;already&nbsp;active)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;any&nbsp;registered&nbsp;events&nbsp;have&nbsp;triggered,&nbsp;mark&nbsp;them&nbsp;active.<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">else</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Wait&nbsp;until&nbsp;at&nbsp;least&nbsp;one&nbsp;</span><span style="color: #0000FF; ">event</span><span style="color: #000000; ">&nbsp;has&nbsp;triggered,&nbsp;and&nbsp;mark&nbsp;it&nbsp;active.<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">&nbsp;(p&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&nbsp;p&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">&nbsp;n_priorities;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">p&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(any&nbsp;</span><span style="color: #0000FF; ">event</span><span style="color: #000000; ">&nbsp;with&nbsp;priority&nbsp;of&nbsp;p&nbsp;</span><span style="color: #0000FF; ">is</span><span style="color: #000000; ">&nbsp;active)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Run&nbsp;all&nbsp;active&nbsp;events&nbsp;with&nbsp;priority&nbsp;of&nbsp;p.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">break</span><span style="color: #000000; ">;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Do&nbsp;not&nbsp;run&nbsp;any&nbsp;events&nbsp;of&nbsp;a&nbsp;less&nbsp;important&nbsp;priority&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(EVLOOP_ONCE&nbsp;was&nbsp;</span><span style="color: #0000FF; ">set</span><span style="color: #000000; ">&nbsp;or&nbsp;EVLOOP_NONBLOCK&nbsp;was&nbsp;</span><span style="color: #0000FF; ">set</span><span style="color: #000000; ">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">break</span><span style="color: #000000; ">;<br />}</span></div><div style="color: #0000ff; "><span style="color: #464646; font-family: simsun; font-size: 14px; line-height: 21px; font-weight: normal; "><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">为方便起见，也可以调用</span></p><h2><span style="word-wrap: normal; word-break: normal; line-height: 28px; font-family: 新宋体; color: #0000ff; font-size: 14pt; font-weight: bold; ">接口</span></h2></span></div><div style="background-color: #eeeeee; font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; color: #0000ff; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;event_base_dispatch(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;event_base&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">base</span><span style="color: #000000; ">);</span></div><div style="color: #0000ff; "><span style="color: #464646; font-family: simsun; font-size: 14px; line-height: 21px; font-weight: normal; "><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">event_base_dispatch（）等同于没有设置标志的event_base_loop（）。所以，event_base_dispatch（）将一直运行，直到没有已经注册的事件了，或者调用了event_base_loopbreak（）或者event_base_loopexit（）为止。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">这些函数定义在&lt;event2/event.h&gt;中，从libevent&nbsp;<wbr>1.0版就存在了。</span></p><h1><span style="word-wrap: normal; word-break: normal; line-height: 28px; font-family: 新宋体; color: #0000ff; font-size: 14pt; font-weight: bold; ">2&nbsp;<wbr>停止循环</span></h1><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">如果想在移除所有已注册的事件之前停止活动的事件循环，可以调用两个稍有不同的函数。</span></p><h2><span style="word-wrap: normal; word-break: normal; line-height: 28px; font-family: 新宋体; color: #0000ff; font-size: 14pt; font-weight: bold; ">接口</span></h2></span></div><div style="background-color: #eeeeee; font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; color: #0000ff; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;event_base_loopexit(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;event_base&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">base</span><span style="color: #000000; ">,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;timeval&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">tv);<br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;event_base_loopbreak(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;event_base&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">base</span><span style="color: #000000; ">);</span></div><div style="color: #0000ff; "><span style="color: #464646; font-family: simsun; font-size: 14px; line-height: 21px; font-weight: normal; "><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">event_base_loopexit（）让event_base在给定时间之后停止循环。如果tv参数为NULL，event_base会立即停止循环，没有延时。如果event_base当前正在执行任何激活事件的回调，则回调会继续运行，直到运行完所有激活事件的回调之才退出。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">event_base_loopbreak（）让event_base立即退出循环。它与event_base_loopexit（base,NULL）的不同在于，如果event_base当前正在执行激活事件的回调，它将在执行完当前正在处理的事件后立即退出。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">注意event_base_loopexit(base,NULL)和event_base_loopbreak(base)在事件循环没有运行时的行为不同：前者安排下一次事件循环在下一轮回调完成后立即停止（就好像带EVLOOP_ONCE标志调用一样）；后者却仅仅停止当前正在运行的循环，如果事件循环没有运行，则没有任何效果。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">这两个函数都在成功时返回0，失败时返回-1。</span></p><h2><span style="word-wrap: normal; word-break: normal; line-height: 28px; font-family: 新宋体; color: #0000ff; font-size: 14pt; font-weight: bold; ">示例：立即关闭</span></h2></span></div><div style="background-color: #eeeeee; font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">event2</span><span style="color: #000000; ">/</span><span style="color: #0000ff; ">event</span><span style="color: #000000; ">.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /><br /></span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Here's&nbsp;a&nbsp;callback&nbsp;function&nbsp;that&nbsp;calls&nbsp;loopbreak&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /></span><span style="color: #0000ff; ">void</span><span style="color: #000000; ">&nbsp;cb(</span><span style="color: #0000ff; ">int</span><span style="color: #000000; ">&nbsp;sock,&nbsp;</span><span style="color: #0000ff; ">short</span><span style="color: #000000; ">&nbsp;what,&nbsp;</span><span style="color: #0000ff; ">void</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">arg)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; ">struct</span><span style="color: #000000; ">&nbsp;event_base&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #0000ff; ">base</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;arg;<br />&nbsp;&nbsp;&nbsp;&nbsp;event_base_loopbreak(</span><span style="color: #0000ff; ">base</span><span style="color: #000000; ">);<br />}<br /><br /></span><span style="color: #0000ff; ">void</span><span style="color: #000000; ">&nbsp;main_loop(</span><span style="color: #0000ff; ">struct</span><span style="color: #000000; ">&nbsp;event_base&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #0000ff; ">base</span><span style="color: #000000; ">,&nbsp;evutil_socket_t&nbsp;watchdog_fd)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; ">struct</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000ff; ">event</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">watchdog_event;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Construct&nbsp;a&nbsp;new&nbsp;event&nbsp;to&nbsp;trigger&nbsp;whenever&nbsp;there&nbsp;are&nbsp;any&nbsp;bytes&nbsp;to<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;read&nbsp;from&nbsp;a&nbsp;watchdog&nbsp;socket.&nbsp;&nbsp;When&nbsp;that&nbsp;happens,&nbsp;we'll&nbsp;call&nbsp;the<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cb&nbsp;function,&nbsp;which&nbsp;will&nbsp;make&nbsp;the&nbsp;loop&nbsp;exit&nbsp;immediately&nbsp;without<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;running&nbsp;any&nbsp;other&nbsp;active&nbsp;events&nbsp;at&nbsp;all.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;watchdog_event&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;event_new(</span><span style="color: #0000ff; ">base</span><span style="color: #000000; ">,&nbsp;watchdog_fd,&nbsp;EV_READ,&nbsp;cb,&nbsp;</span><span style="color: #0000ff; ">base</span><span style="color: #000000; ">);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;event_add(watchdog_event,&nbsp;NULL);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;event_base_dispatch(</span><span style="color: #0000ff; ">base</span><span style="color: #000000; ">);<br />}</span></div><div style="color: #0000ff; "><span style="color: #464646; font-family: simsun; font-size: 14px; line-height: 21px; font-weight: normal; "><h2><span style="word-wrap: normal; word-break: normal; line-height: 28px; font-family: 新宋体; color: #0000ff; font-size: 14pt; font-weight: bold; ">示例：执行事件循环10秒，然后退出</span></h2></span></div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">event2</span><span style="color: #000000; ">/</span><span style="color: #0000FF; ">event</span><span style="color: #000000; ">.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /><br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;run_base_with_ticks(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;event_base&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">base</span><span style="color: #000000; ">)<br />{<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;timeval&nbsp;ten_sec;<br /><br />&nbsp;&nbsp;ten_sec.tv_sec&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">10</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;ten_sec.tv_usec&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br /><br />&nbsp;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Now&nbsp;we&nbsp;run&nbsp;the&nbsp;event_base&nbsp;for&nbsp;a&nbsp;series&nbsp;of&nbsp;10-second&nbsp;intervals,&nbsp;printing<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Tick"&nbsp;after&nbsp;each.&nbsp;&nbsp;For&nbsp;a&nbsp;much&nbsp;better&nbsp;way&nbsp;to&nbsp;implement&nbsp;a&nbsp;10-second<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;timer,&nbsp;see&nbsp;the&nbsp;section&nbsp;below&nbsp;about&nbsp;persistent&nbsp;timer&nbsp;events.&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #000000; ">1</span><span style="color: #000000; ">)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;This&nbsp;schedules&nbsp;an&nbsp;exit&nbsp;ten&nbsp;seconds&nbsp;from&nbsp;now.&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event_base_loopexit(</span><span style="color: #0000FF; ">base</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">ten_sec);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event_base_dispatch(</span><span style="color: #0000FF; ">base</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">Tick</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;}<br />}</span></div><div><span style="color: #464646; font-family: simsun; font-size: 14px; line-height: 21px; font-weight: normal; "><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">有时候需要知道对event_base_dispatch（）或者event_base_loop（）的调用是正常退出的，还是因为调用event_base_loopexit（）或者event_base_break（）而退出的。可以调用下述函数来确定是否调用了loopexit或者break函数。</span></p><h2><span style="word-wrap: normal; word-break: normal; line-height: 28px; font-family: 新宋体; color: #0000ff; font-size: 14pt; font-weight: bold; ">接口</span></h2></span></div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;event_base_got_exit(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;event_base&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">base</span><span style="color: #000000; ">);<br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;event_base_got_break(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;event_base&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">base</span><span style="color: #000000; ">);</span></div><div><span style="color: #464646; font-family: simsun; font-size: 14px; line-height: 21px; font-weight: normal; "><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">这两个函数分别会在循环是因为调用event_base_loopexit（）或者event_base_break（）而退出的时候返回true，否则返回false。下次启动事件循环的时候，这些值会被重设。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">这些函数声明在&lt;event2/event.h&gt;中。event_break_loopexit()函数首次在libevent&nbsp;<wbr>1.0c版本中实现；event_break_loopbreak()首次在libevent&nbsp;<wbr>1.4.3版本中实现。</span></p><h1><span style="word-wrap: normal; word-break: normal; line-height: 28px; font-family: 新宋体; color: #0000ff; font-size: 14pt; font-weight: bold; ">3&nbsp;<wbr>检查内部时间缓存</span></h1><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">有时候需要在事件回调中获取当前时间的近似视图，但不想调用gettimeofday()（可能是因为OS将gettimeofday()作为系统调用实现，而你试图避免系统调用的开销）。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">在回调中，可以请求libevent开始本轮回调时的当前时间视图。</span></p><h2><span style="word-wrap: normal; word-break: normal; line-height: 28px; font-family: 新宋体; color: #0000ff; font-size: 14pt; font-weight: bold; ">接口</span></h2></span></div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;event_base_gettimeofday_cached(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;event_base&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">base</span><span style="color: #000000; ">,<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;timeval&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">tv_out);</span></div><div><span style="color: #464646; font-family: simsun; font-size: 14px; line-height: 21px; font-weight: normal; "><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">如果当前正在执行回调，event_base_gettimeofday_cached()函数设置tv_out参数的值为缓存的时间。否则，函数调用evutil_gettimeofday()获取真正的当前时间。成功时函数返回0，失败时返回负数。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">注意，因为libevent在开始执行回调的时候缓存时间值，所以这个值至少是有一点不精确的。如果回调执行很长时间，这个值将非常不精确。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">这个函数是libevent&nbsp;<wbr>2.0.4-alpha新引入的。</span></p><h1><span style="word-wrap: normal; word-break: normal; line-height: 28px; font-family: 新宋体; color: #0000ff; font-size: 14pt; font-weight: bold; ">4&nbsp;<wbr>转储event_base的状态</span></h1><h2><span style="word-wrap: normal; word-break: normal; line-height: 28px; font-family: 新宋体; color: #0000ff; font-size: 14pt; font-weight: bold; ">接口</span></h2></span></div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;event_base_dump_events(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;event_base&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #0000FF; ">base</span><span style="color: #000000; ">,&nbsp;FILE&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">f);</span></div><div><span style="color: #464646; font-family: simsun; font-size: 14px; line-height: 21px; font-weight: normal; "><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">为帮助调试程序（或者调试libevent），有时候可能需要加入到event_base的事件及其状态的完整列表。调用event_base_dump_events()可以将这个列表输出到指定的文件中。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">这个列表是人可读的，未来版本的libevent将会改变其格式。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">这个函数在libevent&nbsp;<wbr>2.0.1-alpha版本中引入。</span></p><h1><span style="word-wrap: normal; word-break: normal; line-height: 28px; font-family: 新宋体; color: #0000ff; font-size: 14pt; font-weight: bold; ">5&nbsp;<wbr>废弃的事件循环函数</span></h1><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">前面已经讨论过，老版本的libevent&nbsp;<wbr>具有&#8220;当前&#8221;event_base的概念。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">本文讨论的某些事件循环函数具有操作当前event_base的变体。除了没有base参数外，这些函数跟当前新版本函数的行为相同。</span><span class="Apple-style-span" style="font-family: 新宋体; font-size: 19px; font-weight: bold; line-height: 28px; color: #000000; "><img src="http://www.cppblog.com/images/cppblog_com/mysileng/QQ截图20130204173427.jpg" width="1057" height="188" alt="" /></span></p></span></div><div><span style="color: #464646; font-family: simsun; font-size: 14px; line-height: 21px; font-weight: normal; "><div><h2><span style="word-wrap: normal; word-break: normal; line-height: 28px; font-family: 新宋体; color: #0000ff; font-size: 14pt; font-weight: bold; ">注意</span></h2><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: 21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 新宋体; font-size: 10.5pt; ">2.0版本之前的event_base是不支持锁的，所以这些函数并不是完全线程安全的：不允许在执行事件循环的线程之外的其他线程中调用_loopbreak()或者_loopexit()函数。</span></p></div></span></div></span></h2></div></span></div><img src ="http://www.cppblog.com/mysileng/aggbug/197719.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-02-04 17:36 <a href="http://www.cppblog.com/mysileng/archive/2013/02/04/197719.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：libevent参考手册第二章：创建event_base (四) （转）</title><link>http://www.cppblog.com/mysileng/archive/2013/02/04/197718.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Mon, 04 Feb 2013 09:18:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/02/04/197718.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/197718.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/02/04/197718.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/197718.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/197718.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 译自http://www.wangafu.net/~nickm/libevent-book/Ref2_eventbase.html转自:http://blog.sina.com.cn/s/blog_56dee71a0100qdxx.html&nbsp;使用libevent函数之前需要分配一个或者多个event_base结构体。每个event_base结构体持有一个事件集合，可以检测以确定哪个事件是...&nbsp;&nbsp;<a href='http://www.cppblog.com/mysileng/archive/2013/02/04/197718.html'>阅读全文</a><img src ="http://www.cppblog.com/mysileng/aggbug/197718.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-02-04 17:18 <a href="http://www.cppblog.com/mysileng/archive/2013/02/04/197718.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：Libevent参考手册第一章：设置libevent (三) （转）</title><link>http://www.cppblog.com/mysileng/archive/2013/02/04/197717.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Mon, 04 Feb 2013 09:07:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/02/04/197717.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/197717.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/02/04/197717.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/197717.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/197717.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 翻译自：http://www.wangafu.net/~nickm/libevent-book/Ref1_libsetup.html转自http://blog.sina.com.cn/s/blog_56dee71a0100q9ks.htmllibevent有一些被整个进程共享的、影响整个库的全局设置。必须在调用libevent库的任何其他部分之前修改这些设置，否则，libevent会进入不一致的状...&nbsp;&nbsp;<a href='http://www.cppblog.com/mysileng/archive/2013/02/04/197717.html'>阅读全文</a><img src ="http://www.cppblog.com/mysileng/aggbug/197717.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-02-04 17:07 <a href="http://www.cppblog.com/mysileng/archive/2013/02/04/197717.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：Libevent参考手册：前言 (二) （转）</title><link>http://www.cppblog.com/mysileng/archive/2013/02/04/197716.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Mon, 04 Feb 2013 08:58:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/02/04/197716.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/197716.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/02/04/197716.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/197716.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/197716.html</trackback:ping><description><![CDATA[<div><span style="color: #464646; font-family: simsun; "><h1><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">翻译自：<a title="http://www.wangafu.net/~nickm/libevent-book/Ref0_meta.html" href="http://www.wangafu.net/~nickm/libevent-book/Ref0_meta.html" style="text-decoration: none; color: #41646f; ">http://www.wangafu.net/~nickm/libevent-book/Ref0_meta.html<br /><span style="color: #000000; ">转自:</span></a><a href="http://blog.sina.com.cn/s/blog_56dee71a0100q7j6.html"><span style="color: #000000; ">http://blog.sina.com.cn/s/blog_56dee71a0100q7j6.html</span></a><br /><br /></span></h1><h1><span style="word-wrap: normal; word-break: normal; line-height: 28px; font-family: 宋体; color: #0000ff; font-size: 14pt; font-weight: bold; ">1&nbsp;<wbr>&nbsp;从一万英尺外看Libevent</span></h1><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">Libevent是用于编写高速可移植非阻塞IO应用的库，其设计目标是：</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">可移植性：使用libevent编写的程序应该可以在libevent支持的所有平台上工作。即使没有好的方式进行非阻塞IO，libevent也应该支持一般的方式，让程序可以在受限的环境中运行。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">速度：libevent尝试使用每个平台上最高速的非阻塞IO实现，并且不引入太多的额外开销。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">可扩展性：libevent被设计为程序即使需要上万个活动套接字的时候也可以良好工作。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">方便：无论何时，最自然的使用libevent编写程序的方式应该是稳定的、可移植的。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; ">&nbsp;<wbr></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">libevent由下列组件构成：</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">evutil：用于抽象不同平台网络实现差异的通用功能。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">event和event_base：libevent的核心，为各种平台特定的、基于事件的非阻塞IO后端提供抽象API，让程序可以知道套接字何时已经准备好，可以读或者写，并且处理基本的超时功能，检测OS信号。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">bufferevent：为libevent基于事件的核心提供使用更方便的封装。除了通知程序套接字已经准备好读写之外，还让程序可以请求缓冲的读写操作，可以知道何时IO已经真正发生。（bufferevent接口有多个后端，可以采用系统能够提供的更快的非阻塞IO方式，如Windows中的IOCP。）</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">evbuffer：在bufferevent层之下实现了缓冲功能，并且提供了方便有效的访问函数。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">evhttp：一个简单的HTTP客户端/服务器实现。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">evdns：一个简单的DNS客户端/服务器实现。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">evrpc：一个简单的RPC实现。</span></p><h1><span style="word-wrap: normal; word-break: normal; line-height: 28px; font-family: 宋体; color: #0000ff; font-size: 14pt; font-weight: bold; ">2&nbsp;<wbr>&nbsp;库</span></h1><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">创建libevent时，默认安装下列库：</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">libevent_core：所有核心的事件和缓冲功能，包含了所有的event_base、evbuffer、bufferevent和工具函数。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">libevent_extra：定义了程序可能需要，也可能不需要的协议特定功能，包括HTTP、DNS和RPC。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">libevent：这个库因为历史原因而存在，它包含libevent_core和libevent_extra的内容。不应该使用这个库，未来版本的libevent可能去掉这个库。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">某些平台上可能安装下列库：</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">libevent_pthreads：添加基于pthread可移植线程库的线程和锁定实现。它独立于libevent_core，这样程序使用libevent时就不需要链接到pthread，除非是以多线程方式使用libevent。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: left; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">libevent_openssl：这个库为使用bufferevent和OpenSSL进行加密的通信提供支持。它独立于libevent_core，这样程序使用libevent时就不需要链接到OpenSSL，除非是进行加密通信。</span></p><h1><span style="word-wrap: normal; word-break: normal; line-height: 28px; font-family: 宋体; color: #0000ff; font-size: 14pt; font-weight: bold; ">3&nbsp;头文件</span></h1><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: left; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">libevent公用头文件都安装在event2目录中，分为三类：</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: left; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">API头文件：定义libevent公用接口。这类头文件没有特定后缀。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: left; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">兼容头文件：为已废弃的函数提供兼容的头部包含定义。不应该使用这类头文件，除非是在移植使用较老版本libevent的程序时。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: left; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">结构头文件：这类头文件以相对不稳定的布局定义各种结构体。这些结构体中的一些是为了提供快速访问而暴露；一些是因为历史原因而暴露。直接依赖这类头文件中的任何结构体都会破坏程序对其他版本libevent的二进制兼容性，有时候是以非常难以调试的方式出现。这类头文件具有后缀&#8220;_struct.h&#8221;。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: left; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">（还存在不在event2目录中的较老版本libevent的头文件，请参考下节：如果需要使用老版本libevent）</span></p><h1><span style="word-wrap: normal; word-break: normal; line-height: 28px; font-family: 宋体; color: #0000ff; font-size: 14pt; font-weight: bold; ">4&nbsp;如果需要使用老版本libevent</span></h1><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: left; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">libevent 2.0以更合理的、不易出错的方式修正了API。如果可能，编写新程序时应该使用libevent 2.0。但是有时候可能需要使用较老的API，例如在升级已存的应用时，或者支持因为某些原因不能安装2.0或者更新版本libevent的环境时。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: left; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">较老版本的libevent头文件较少，也不安装在event2目录中。<br /><img src="http://www.cppblog.com/images/cppblog_com/mysileng/QQ截图20130204165731.jpg" width="980" height="214" alt="" /><br /></span></p><div><span style="font-family: simsun; "><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: left; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">在2.0以及以后版本的libevent中，老的头文件仍然会作为新头文件的封装而存在。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: left; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">其他关于使用较老版本的提示：</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: left; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">1.4版之前只有一个库libevent，它包含现在分散到libevent_core和libevent_extra中的所有功能。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: left; text-indent: -21pt; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: Wingdings; font-size: 10.5pt; ">v</span>&nbsp;<span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">2.0版之前不支持锁定：只有确定不同时在多个线程中使用同一个结构体时，libevent才是线程安全的。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: left; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">下面的节还将讨论特定代码区域可能遇到的已经废弃的API。</span></p><h1><span style="word-wrap: normal; word-break: normal; line-height: 28px; font-family: 宋体; color: #0000ff; font-size: 14pt; font-weight: bold; ">5&nbsp;关于版本状态的提示</span></h1><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">1.4.7及以前版本应该被认为是完全废弃的。1.3之前的版本应该被认为是充满bug的。</span></p><p style="margin-top: 0pt; margin-right: 0px; margin-bottom: 0pt; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; list-style-type: none; list-style-position: initial; list-style-image: initial; border-style: initial; border-color: initial; word-wrap: normal; word-break: normal; line-height: 21px; text-align: justify; "><span style="word-wrap: normal; word-break: normal; line-height: 21px; font-family: 宋体; font-size: 10.5pt; ">（此外，不要向libevent维护者发送任何关于1.4.x或者更早版本的新特征，这些版本被认为是稳定的发布版本。如果在1.3x或者更早版本中发现bug，在报告之前请确定在最新的稳定发布版本中问题仍然存在：后续发布可能已经解决了问题。）</span></p></span></div><br /></span><p>&nbsp;</p></div><img src ="http://www.cppblog.com/mysileng/aggbug/197716.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-02-04 16:58 <a href="http://www.cppblog.com/mysileng/archive/2013/02/04/197716.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译：使用Libevent的快速可移植非阻塞网络编程：异步IO简介 (一)  (转)</title><link>http://www.cppblog.com/mysileng/archive/2013/02/04/197715.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Mon, 04 Feb 2013 08:24:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/02/04/197715.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/197715.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/02/04/197715.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/197715.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/197715.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 原文出处：http://www.wangafu.net/~nickm/libevent-book/01_intro.html转自:&nbsp;http://blog.sina.com.cn/s/blog_56dee71a0100q2i9.html大多数程序员从阻塞IO调用开始学习。如果调用在操作完成之前，或者足够的时间已经流逝使得网络栈放弃操作之前，不会返回，那么就是异步的。比如说，在TCP连接上...&nbsp;&nbsp;<a href='http://www.cppblog.com/mysileng/archive/2013/02/04/197715.html'>阅读全文</a><img src ="http://www.cppblog.com/mysileng/aggbug/197715.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-02-04 16:24 <a href="http://www.cppblog.com/mysileng/archive/2013/02/04/197715.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>libevent: evbuffer缓冲 (转)</title><link>http://www.cppblog.com/mysileng/archive/2013/02/01/197671.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Fri, 01 Feb 2013 12:15:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/02/01/197671.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/197671.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/02/01/197671.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/197671.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/197671.html</trackback:ping><description><![CDATA[<div><span style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; line-height: normal; "><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; "><strong>前言</strong></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; 可以说对于任何网络库(模块)而言，一个缓冲模块都是必不可少的。缓冲模块主要用于缓冲从网络接收到的数据，以及<br />用户提交的数据(用于发送)。很多时候，我们还需要将网络模块层(非TCP层)的这些缓冲数据拷贝到用户层，而这些内存拷贝<br />都会消耗时间。<br />&nbsp;&nbsp;&nbsp; 在这里，我简要分析下libevent的相关代码(event.h和buffer.c)。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; "><strong>结构</strong></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; 关于libevent的缓冲模块，主要就是围绕evbuffer结构体展开。先看下evbuffer的定义：<br /></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;evbuffer{<br />&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;当前有效缓冲区的内存起始地址</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;u_char&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">buffer;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;整个分配(realloc)用来缓冲的内存起始地址</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;u_char&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">orig_buffer;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;origin_buffer和buffer之间的字节数</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;size_t&nbsp;misalign;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;整个分配用来缓冲的内存字节数</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;size_t&nbsp;totallen;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;当前有效缓冲区的长度(字节数)</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;size_t&nbsp;off;&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">回到函数，当缓冲区有变化的时候会被调用</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #000000; ">*</span><span style="color: #000000; ">cb)(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;evbuffer&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">,&nbsp;size_t,&nbsp;size_t,&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">回调函数的参数</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">cbarg;&nbsp;<br />};</span></div><div><span style="font-size: small; ">&nbsp;libevent的缓冲是一个连续的内存区域，其处理数据的方式(写数据和读数据)更像一个队列操作方式：从后写入，从前<br />读出。evbuffer分别设置相关指针(一个指标)用于指示读出位置和写入位置。其大致结构如图：</span></div><img src="http://www.cppblog.com/images/cppblog_com/mysileng/evbuffer_str_thumb.jpg" width="290" height="140" alt="" /><br /><div><span style="font-size: small; ">&nbsp;&nbsp; &nbsp;orig_buffer指向由realloc分配的连续内存区域，buffer指向有效数据的内存区域，totallen表示orig_buffer指向的内存<br />区域的大小，misalign表示buffer相对于orig_buffer的偏移，off表示有效数据的长度。</span></div><br /><div><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; "><strong>实际运作</strong></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; 这里我将结合具体的代码分析libevent是如何操作上面那个队列式的evbuffer的，先看一些辅助函数：<br /><br /></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;evbuffer_drain(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;evbuffer&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">buf,&nbsp;size_t&nbsp;len)</span></div><p>&nbsp;</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; 该函数主要操作一些指标，当每次从evbuffer里读取数据时，libevent便会将buffer指针后移，同时增大misalign，减小off，<br />而该函数正是做这件事的。说白了，该函数就是用于调整缓冲队列的前向指标。<br /><br /><br /></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;evbuffer_expand(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;evbuffer&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">buf,&nbsp;size_t&nbsp;datlen)</span></div><p>&nbsp;</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; 该函数用于扩充evbuffer的容量。每次向evbuffer写数据时，都是将数据写到buffer+off后，buffer到buffer+off之间已被<br />使用，保存的是有效数据，而orig_buffer和buffer之间则是因为读取数据移动指标而形成的无效区域。<br />&nbsp;&nbsp;&nbsp; evbuffer_expand的扩充策略在于，首先判断如果让出orig_buffer和buffer之间的空闲区域是否可以容纳添加的数据，如果<br />可以，则移动buffer和buffer+off之间的数据到orig_buffer和orig_buffer+off之间(有可能发生内存重叠，所以这里移动调用的<br />是memmove)，然后把新的数据拷贝到orig_buffer+off之后；如果不可以容纳，那么重新分配更大的空间(realloc)，同样会移动<br />数据。<br />&nbsp;&nbsp;&nbsp; 扩充内存的策略为：确保新的内存区域最小尺寸为256，且以乘以2的方式逐步扩大(256、512、1024、...)。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; 了解了以上两个函数，看其他函数就比较简单了。可以看看具体的读数据和写数据：<br /><br /><br /></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;evbuffer_add(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;evbuffer&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">buf,&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">data,&nbsp;size_t&nbsp;datlen)</span></div><p>&nbsp;</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; 该函数用于添加一段用户数据到evbuffer中。很简单，就是先判断是否有足够的空闲内存，如果没有则调用evbuffer_expand<br />扩充之，然后直接memcpy，更新off指标。<br /><br /><br /></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;evbuffer_remove(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;evbuffer&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">buf,&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">data,&nbsp;size_t&nbsp;datlen)</span></div><p>&nbsp;</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; ">&nbsp;&nbsp;&nbsp; 该函数用于将evbuffer中的数据复制给用户空间(读数据)。简单地将数据memcpy，然后调用evbuffer_drain移动相关指标。<br /><br /><br /></p><div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;evbuffer</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;evbuffer_new(</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">)</span></div><div><span style="font-family: 宋体; font-size: 13px; line-height: 26px; ">动态分配一个struct evbuffer结构，需要调用evbuffer_free释放内存。<br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;evbuffer_free(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;evbuffer&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">buffer)</span></div><div>释放buffer所占用的内存。<br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;evbuffer_add_buffer(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;evbuffer&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">outbuf,&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;evbuffer&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">inbuf)</span></div><div><span style="color: #666666; font-family: 宋体, Arial; font-size: 12px; "><p align="left" style="margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: left; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: white; background-position: initial initial; background-repeat: initial initial; "><span style="font-size: 10pt; font-family: 宋体; color: black; ">移动数据从一个evbuffer到另一个evbuffer。</span></p><p align="left" style="margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: left; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: white; background-position: initial initial; background-repeat: initial initial; "><span style="font-size: 10pt; font-family: 宋体; color: black; ">实际上还是调用了evbuffer_add添加数据到outbuf中。但会清除inbuf中的数据。</span></p><p align="left" style="margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: left; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: white; background-position: initial initial; background-repeat: initial initial; "><span style="font-size: 10pt; font-family: 宋体; color: black; ">返回值：成功返回0， 失败返回-1。</span></p></span></div><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;evbuffer_add_printf(&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;evbuffer&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;fmt,&nbsp;<img src="http://www.cppblog.com/Images/dot.gif" alt="" />)</span></div><div>添加一个格式化的字符串到evbuffer尾部。</div><br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><span style="color: #000000; ">u_char&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">evbuffer_find(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;evbuffer&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">buffer,&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;u_char&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">what,&nbsp;size_t&nbsp;len)</span></div><div><span style="color: #666666; font-family: 宋体, Arial; font-size: 12px; "><p align="left" style="margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: left; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: white; background-position: initial initial; background-repeat: initial initial; "><span style="font-size: 10pt; font-family: 宋体; color: black; ">查找缓冲区中是否存在指定的字符串what。</span></p><p style="margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: white; background-position: initial initial; background-repeat: initial initial; "><span style="font-size: 10pt; font-family: 宋体; color: black; ">注意这里使用的是u_char类型，说明有可能查找的数据不是以&#8217;\0&#8217;结尾</span></p><p align="left" style="margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: left; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: white; background-position: initial initial; background-repeat: initial initial; "><span style="font-size: 10pt; font-family: 宋体; color: black; ">如果存在返回指向字符串what的指针，没有则返回NULL。</span></p></span></div><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;evbuffer_read(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;evbuffer&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">buf,&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;fd,&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;howmuch)</span></div><div>调用read/recv函数，从文件描述符fd上读取数据到evbuffer中。如果缓冲区不够，调用evbuffer_expand扩充缓冲区。</div><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;evbuffer_write(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;evbuffer&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">buffer,&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;fd)</span></div><div>把缓冲区中的数据，调用send/write函数写入文件描述符fd上， 如果send/write函数写入的字节数大于0，则调用evbuffer_drain删除已写的数据。</div><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">evbuffer_readline(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;evbuffer&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">buffer)</span></div><div><span style="color: #666666; font-family: 宋体, Arial; font-size: 12px; "><p align="left" style="margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: left; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: white; background-position: initial initial; background-repeat: initial initial; "><span style="font-size: 10pt; font-family: 宋体; color: black; ">读取数据以"\r\n","\n\r", "\r"&nbsp;或者&nbsp;"\n"结尾。</span></p><p align="left" style="margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: left; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: white; background-position: initial initial; background-repeat: initial initial; "><span style="font-size: 10pt; font-family: 宋体; color: black; ">返回动态分配内存，需要调用者自己使用free来释放内存。返回一个以</span><span style="font-size: 10pt; font-family: 'Times New Roman', serif; color: black; ">&#8220;</span><span style="font-size: 10pt; font-family: 宋体; color: black; ">\0</span><span style="font-size: 10pt; font-family: 'Times New Roman', serif; color: black; ">&#8221;</span><span style="font-size: 10pt; font-family: 宋体; color: black; ">结尾的字符串。</span></p></span></div><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;evbuffer_setcb(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;evbuffer&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">buffer,<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #000000; ">*</span><span style="color: #000000; ">cb)(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;evbuffer&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">,&nbsp;size_t,&nbsp;size_t,&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">),<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">cbarg)</span></div><div>设置回调函数。当缓冲区中发生变化时， 调用设置的回调函数。</div><br /><div><span style="color: #666666; font-family: 宋体, Arial; font-size: 12px; "><p align="left" style="margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: left; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: white; background-position: initial initial; background-repeat: initial initial; "><span style="font-size: 10pt; font-family: 宋体; color: black; ">Evbuffer</span><span style="font-size: 10pt; font-family: 宋体; color: black; ">提供的API已经全部介绍完毕，接下来我们通过一个实例进一步学习如何使用evbuffer,&nbsp;想要使用evbuffer，系统里必须已经安装了libevent。</span></p><p align="left" style="margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-align: left; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: white; background-position: initial initial; background-repeat: initial initial; "><span style="font-size: 10pt; font-family: 宋体; color: black; ">例子代码如下：evbuffer-test.c</span></p></span></div><div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">stdio.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #000000; ">#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">string</span><span style="color: #000000; ">.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #000000; ">#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">assert.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #000000; "><br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">引入libevent头文件</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">#include&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">event.h</span><span style="color: #000000; ">"</span><span style="color: #000000; "><br /></span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;main(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;argc,&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">**</span><span style="color: #000000; ">&nbsp;argv)<br /></span><span style="color: #000000; ">{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;evbuffer</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;buff&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;NULL;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;c,&nbsp;c2[</span><span style="color: #000000; ">3</span><span style="color: #000000; ">]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;{</span><span style="color: #000000; ">0</span><span style="color: #000000; ">};<br />&nbsp;&nbsp; &nbsp;</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">buff&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;evbuffer_new();<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">assert(buff&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;NULL);<br />&nbsp;&nbsp; &nbsp;</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">evbuffer_add(buff,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">1</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">evbuffer_add(buff,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">2</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">evbuffer_add(buff,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">3</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">evbuffer_add_printf(buff,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">%d%d</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">4</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">5</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">assert(buff</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">off&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">5</span><span style="color: #000000; ">);<br /></span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">evbuffer_remove(buff,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">c,&nbsp;</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">));<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">assert(c&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">'</span><span style="color: #000000; ">1</span><span style="color: #000000; ">'</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">evbuffer_remove(buff,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">c,&nbsp;</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">));<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">assert(c&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">'</span><span style="color: #000000; ">2</span><span style="color: #000000; ">'</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">evbuffer_remove(buff,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">c,&nbsp;</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">));<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">assert(c&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">'</span><span style="color: #000000; ">3</span><span style="color: #000000; ">'</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">evbuffer_remove(buff,&nbsp;c2,&nbsp;</span><span style="color: #000000; ">2</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">assert(strcmp(c2,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">45</span><span style="color: #000000; ">"</span><span style="color: #000000; ">)&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">);<br />&nbsp;&nbsp; &nbsp;</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">assert(buff</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">off&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">evbuffer_add(buff,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">test\r\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">6</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">assert(buff</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">off&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">6</span><span style="color: #000000; ">);<br />&nbsp;&nbsp; &nbsp;</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;line&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;evbuffer_readline(buff);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">assert(strcmp(line,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">test</span><span style="color: #000000; ">"</span><span style="color: #000000; ">)&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">0</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">assert(buff</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">off&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">free(line);<br />&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">evbuffer_free(buff);<br />&nbsp;&nbsp; &nbsp;</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">printf(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">ok\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />&nbsp;&nbsp; &nbsp;</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />}</span></div></div></span></div><p>&nbsp;</p></div><p>&nbsp;</p></span></div><img src ="http://www.cppblog.com/mysileng/aggbug/197671.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-02-01 20:15 <a href="http://www.cppblog.com/mysileng/archive/2013/02/01/197671.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>libevent学习资料 （转）</title><link>http://www.cppblog.com/mysileng/archive/2013/01/17/197349.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Thu, 17 Jan 2013 09:34:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/01/17/197349.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/197349.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/01/17/197349.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/197349.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/197349.html</trackback:ping><description><![CDATA[<span style="color: #333333; font-size: 14px; line-height: 26px; background-color: #ffffff; font-family: monospace;">The libevent API provides a mechanism to execute a callback function when a<br />specific event occurs on a file descriptor or after a timeout has been<br />reached. Furthermore, libevent also support callbacks due to signals or<br />regular timeouts.<br /><br />libevent is meant to replace the event loop found in event driven network<br />servers. An application just needs to call event_dispatch() and then add or<br />remove events dynamically without having to change the event loop.<br /><br /><br />官网<br /><span style="color: #6a5acd;"><u><a href="http://libevent.org/" style="color: #336699; text-decoration: initial;">http://libevent.org/</a></u></span><br /><br />Fast portable non-blocking network programming with Libevent<br /><span style="color: #6a5acd;"><u><a href="http://www.wangafu.net/~nickm/libevent-book/" style="color: #336699; text-decoration: initial;">http://www.wangafu.net/~nickm/libevent-book/</a></u></span><br /><br /><br />epoll学习笔记<br /><span style="color: #6a5acd;"><u><a href="http://www.cppblog.com/converse/archive/2008/04/29/48482.aspx" style="color: #336699; text-decoration: initial;">http://www.cppblog.com/converse/archive/2008/04/29/48482.aspx</a></u></span><br /><br />libevent事件处理框架分析<br /><span style="color: #6a5acd;"><u><a href="http://www.cppblog.com/converse/archive/2009/01/03/71040.aspx" style="color: #336699; text-decoration: initial;">http://www.cppblog.com/converse/archive/2009/01/03/71040.aspx</a></u></span><br /><br />libevent入门教程：Echo Server based on libevent<br /><span style="color: #6a5acd;"><u><a href="http://www.felix021.com/blog/read.php?2068" style="color: #336699; text-decoration: initial;">http://www.felix021.com/blog/read.php?2068</a></u></span><br /><br />libevent源码深度剖析<br /><span style="color: #6a5acd;"><u><a href="http://blog.csdn.net/sparkliang/article/category/660506" style="color: #336699; text-decoration: initial;">http://blog.csdn.net/sparkliang/article/category/660506<br /><br /></a></u></span></span><span style="color: #333333; font-family: monospace; line-height: 26px; background-color: #ffffff;">libevent源码分析</span><br /><div><span style="font-size: 8pt;"><a href="http://www.cnblogs.com/hustcat/archive/2010/08/31/1814022.html">http://www.cnblogs.com/hustcat/archive/2010/08/31/1814022.html</a><br /><br /><br /></span></div><span style="color: #333333; font-size: 14px; line-height: 26px; background-color: #ffffff; font-family: monospace;">How to use epoll? A complete example in C<br /></span><p style="color: #333333; font-family: Arial; font-size: 14px; line-height: 26px; background-color: #ffffff;"><span style="font-family: monospace;"><span style="color: #6a5acd;"><u><a href="https://banu.com/blog/2/how-to-use-epoll-a-complete-example-in-c/" style="color: #336699; text-decoration: initial;">https://banu.com/blog/2/how-to-use-epoll-a-complete-example-in-c/</a></u></span></span></p><img src ="http://www.cppblog.com/mysileng/aggbug/197349.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-01-17 17:34 <a href="http://www.cppblog.com/mysileng/archive/2013/01/17/197349.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>