<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_MrDB's 技术随笔</title><subtitle type="text">——关注Linux、数据库和高性能服务器</subtitle><id>http://feed.cnblogs.com/blog/u/26761/rss</id><updated>2012-01-15T14:03:40Z</updated><author><name>MrDB</name><uri>http://www.cnblogs.com/hustcat/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hustcat/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/26761/rss"/><entry><id>http://www.cnblogs.com/hustcat/archive/2012/01/11/2319249.html</id><title type="text">乱谈服务器编程</title><summary type="text">做了快一年了服务器端开发了，前前后后参与了好几个项目，也看了许多开源，以及公司内部的网络框架，日久难免生情，所以乱谈一下server编程。讨论几个老生常谈的问题：I/O模型、epoll实现、epoll为什么比poll高效，最后讨论一下epoll的线程安全性。</summary><published>2012-01-11T06:39:00Z</published><updated>2012-01-11T06:39:00Z</updated><author><name>MrDB</name><uri>http://www.cnblogs.com/hustcat/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hustcat/archive/2012/01/11/2319249.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hustcat/archive/2012/01/11/2319249.html"/><content type="html">&lt;p align="center"&gt;&lt;strong&gt;&lt;span style="font-size:16.0pt;font-family:宋体;"&gt;乱谈服务器编程&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="font-size:14.0pt;font-family:宋体;Times New Roman&amp;quot;;Times New Roman&amp;quot;"&gt;第一部分&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;&lt;span style="font-size:14.0pt;font-family:宋体;Times New Roman&amp;quot;;Times New Roman&amp;quot;"&gt;编程模型&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;1&lt;span style="font-family:宋体;Times New Roman&amp;quot;;Times New Roman&amp;quot;"&gt;、服务器编程模型&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;关于&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;server&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;编程模型，大师&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;stevens&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;在他的《&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;UNP&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;》一书中已经做了详细论述，这里不再重复，这里主要讲一下我的一些理解。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;从线程的角度，可以分为两类，一是单线程，一是多线程。先来看单线程模型。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;1.1&lt;span style="font-family:Cambria;"&gt;、单线程模型&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;整个进程只有一个线程，由于只有一个线程，所以要实现高性能，必须与&amp;#8220;&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;non-blocking&amp;nbsp;IO&amp;nbsp;+&amp;nbsp;IO&amp;nbsp;multiplexing&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;&amp;#8221;相结合。程序基本模型如下：&lt;/span&gt;&lt;/p&gt;  &lt;div style="border:solid black 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;background:silver"&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;epoll_event ev&lt;span style="color:#993300"&gt;, events[MAX_EVENTS];&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;int &lt;/span&gt;&lt;/strong&gt;listen_sock&lt;span style="color:#993300"&gt;, nfds&lt;span style="color:#993300"&gt;, &lt;/span&gt;epollfd&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;/* Set up listening socket, 'listen_sock' (socket(),bind(), listen()) */&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;/* 1. &lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;创建一个&lt;/span&gt;&lt;span style="color:green"&gt;epoll&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;描述符&lt;/span&gt;&lt;span style="color:green"&gt; */&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;epollfd &lt;span style="color:#993300"&gt;= epoll_create(10);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;ev&lt;span style="color:#993300"&gt;.events &lt;span style="color:#993300"&gt;= &lt;/span&gt;EPOLLIN&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;ev&lt;span style="color:#993300"&gt;.data&lt;span style="color:#993300"&gt;.&lt;/span&gt;fd &lt;span style="color:#993300"&gt;= &lt;/span&gt;listen_sock&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;/* 2. &lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;注册监听事件&lt;/span&gt;&lt;span style="color:green"&gt; */&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;epoll_ctl(epollfd&lt;span style="color:#993300"&gt;, EPOLL_CTL_ADD&lt;span style="color:#993300"&gt;, &lt;/span&gt;listen_sock&lt;span style="color:#993300"&gt;, &amp;amp;&lt;/span&gt;ev);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:blue"&gt;for &lt;/span&gt;(;;) {&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* 3. &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;监听事件&lt;/span&gt;&lt;span style="color:green"&gt; */&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; nfds &lt;span style="color:#993300"&gt;= &lt;/span&gt;epoll_wait(epollfd&lt;span style="color:#993300"&gt;, &lt;/span&gt;events&lt;span style="color:#993300"&gt;, &lt;/span&gt;MAX_EVENTS&lt;span style="color:#993300"&gt;, -&lt;/span&gt;1);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* 4. &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;处理事件&lt;/span&gt;&lt;span style="color:green"&gt; */&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;for &lt;/span&gt;(n &lt;span style="color:#993300"&gt;= &lt;/span&gt;0&lt;span style="color:#993300"&gt;; &lt;/span&gt;n &amp;lt; nfds&lt;span style="color:#993300"&gt;; ++&lt;/span&gt;n) {&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (events[i].data&lt;span style="color:#993300"&gt;.&lt;/span&gt;fd == listener_fd) {&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HandleAccept(events[i].data&lt;span style="color:#993300"&gt;.&lt;/span&gt;fd);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:blue"&gt;continue&lt;/span&gt;&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (events[i].events &lt;span style="color:#993300"&gt;&amp;amp; &lt;/span&gt;EPOLLIN) {&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HandleRead(events[i].data&lt;span style="color:#993300"&gt;.&lt;/span&gt;fd);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (events[i].events &lt;span style="color:#993300"&gt;&amp;amp; &lt;/span&gt;EPOLLOUT) {&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HandleWrite(events[i].data&lt;span style="color:#993300"&gt;.&lt;/span&gt;fd);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;}&lt;/p&gt;  &lt;/div&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;该模型的代表主要有&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;haproxy&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;、&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;nginx&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;等，另外&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;libevent&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;本身也是单线程的。相对于多线程，单线程&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;server&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;没有线程切换以及加锁的开销，劣势是不能充分利用&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;CPU&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的多核优势，不过，这可以通过多个进程来解决。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;另外，这种模型编程也很简单，因为简单，所以是编写高性能&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;server&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的首选。公司内部的网络框架&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;Srvframework&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;、&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;GNP&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;都属于这类范畴。&lt;/span&gt;&lt;span style="font-family:Cambria"&gt; Alan Cox&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;曾说：&amp;#8220;线程是为不懂状态机的人准备的&amp;#8221;&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;[9]&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。的确，单线程&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;+&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;状态机可以做很多事情。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;1.2&lt;span style="font-family:Cambria;"&gt;、多线程模型&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;进程有多个线程，一般来说，可以将&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;server&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的线程分成两类：&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;I/O&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;线程和工作线程。由此又可以将多线程模型大体分成两类：单一&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;I/O&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;线程&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;+&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;多个工作线程、多个&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;I/O&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;线程&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;(&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;工作线程&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。另外，不论是单线程，还是多线程，&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;non-blocking&amp;nbsp;IO&amp;nbsp;+&amp;nbsp;IO&amp;nbsp;multiplexing&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;都是必选的。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;(1)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;单一&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;I/O&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;线程&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;+&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;多个工作线程&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;这种模型下，&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;I/O&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;线程负责&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;event loop&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;、&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;I/O&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;操作，工作线程负责实际的业务逻辑处理，&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;I/O&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;线程与工作线程可以通过阻塞队列&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;/&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;共享内存等方式进行数据交换，队列&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;/&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;共享内存的访问需要加锁。实际上，这种模型本质上与&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;1.2&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中单线程是类似的，只不过这里的业务逻辑交由单独的工作处理，它有大家都很熟悉的名字&amp;#8212;&amp;#8212;半同步&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;/&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;半异步模型&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;(HS/HA)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;Taf&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;属于这类。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;(2)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;多个&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;I/O&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;线程&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;(&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;工作线程&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;)&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;这种模型下，每个&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;I/O&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;线程都有一个&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;event loop&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，另外，这里的工作线程可有可无，而且通常是没有，即&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;I/O&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;线程既处理&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;I/O&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，又进行业务逻辑计算。大家熟悉的&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;leader/follower(L/F)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;以及&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;muti-reactor(M-R)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;模型都属于这类，这方面的资料很多，见参考文献，不再讨论。&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;Memcached&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;使用的&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;M-R&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ICE&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;使用的&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;L/F&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;1.3&lt;span style="font-family:Cambria;"&gt;、小结&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;个人认为：&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;(1)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;单线程模型实现简单，如果业务逻辑不复杂，是实现高性能&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;server&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的首选，比如&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;proxy&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;之类的&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;server&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;(2)HS/HA&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;很清晰，如果业务逻辑很复杂，比如&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;database&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，可以考虑这种模型。&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;(3)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;如果你想充分利用多&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;CPU&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，当然可以考虑&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;L/F&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;或者&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;M-R&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。但是值得一提的是，&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;L/F&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中会有锁的开销，而&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;M-R&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中没有锁的开销，但&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;M-R&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的线程切换的开销要高于&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;L/F&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。根据同事的一些测试，对于短连接&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;L/F&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的结果好于&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;M-R&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，而对于长连接，&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;M-R&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;要好于&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;L/F&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="font-size:14.0pt; font-family:宋体;Times New Roman&amp;quot;;"&gt;第二部分&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;&lt;span style="font-size:14.0pt; font-family:宋体;Times New Roman&amp;quot;;"&gt;理解&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span style="font-size:14.0pt;"&gt;epoll&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;2&lt;span style="font-family:宋体;Times New Roman&amp;quot;;Times New Roman&amp;quot;"&gt;、&lt;/span&gt;epoll&lt;span style="font-family:宋体;Times New Roman&amp;quot;;Times New Roman&amp;quot;"&gt;的实现&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;2.1&lt;span style="font-family:Cambria;"&gt;、核心数据结构&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;2.1.1&lt;span style="font-family:宋体;Times New Roman&amp;quot;;Times New Roman&amp;quot;"&gt;、&lt;/span&gt;epoll&lt;span style="font-family: 宋体;Times New Roman&amp;quot;;Times New Roman&amp;quot;"&gt;实例&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;当用系统调用函数&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_create&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;创建一个&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;环境时，用户态得到&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll fd&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，内核态创建一个&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;eventpoll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;：&lt;/span&gt;&lt;/p&gt;  &lt;div style="border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt; background:silver"&gt;  &lt;p&gt;&lt;span style="color:green"&gt;//fs/eventpoll.c&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;struct eventpoll {&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* Protect the access to this structure */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; spinlock_t lock&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/*&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* This mutex is used to ensure that files are not removed&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* while epoll is using them. This is held during the event&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* collection loop, the file cleanup path, the epoll file exit&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* code and the ctl operations.&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*/&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;mutex mtx&lt;span style="color:#993300"&gt;; &lt;/span&gt;&lt;span style="color:green"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;主要用于&lt;/span&gt;&lt;span style="color:green"&gt;epoll_ctl&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;的并发&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* Wait queue used by sys_epoll_wait() */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; wait_queue_head_t wq&lt;span style="color:#993300"&gt;; &lt;/span&gt;&lt;span style="color:green"&gt;///sys_epoll_wait()&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;使用的等待队列&lt;/span&gt;&lt;span style="color:green"&gt;, process list&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* Wait queue used by file-&amp;gt;poll() */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; wait_queue_head_t poll_wait&lt;span style="color:#993300"&gt;; &lt;/span&gt;&lt;span style="color:green"&gt;///file-&amp;gt;poll()&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;使用的等待队列&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* List of ready file descriptors */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;list_head rdllist&lt;span style="color:#993300"&gt;; &lt;/span&gt;&lt;span style="color:green"&gt;///ready list&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* RB tree root used to store monitored fd structs */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;rb_root rbr&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/*&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* This is a single linked list that chains all the "struct epitem" that&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* happened while transferring ready events to userspace w/out&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* holding -&amp;gt;lock.&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*/&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;epitem &lt;span style="color:#993300"&gt;*&lt;/span&gt;ovflist&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* The user that created the eventpoll descriptor */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;user_&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;&lt;span style="color:#993300"&gt;*&lt;/span&gt;user&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:#993300"&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;理解这个结构是理解&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的开始，所以这里有必要解释一下。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;我们知道在&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;Unix/Linux&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中，一切都是文件，对于&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;实例的&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;eventpoll&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;通常保存在&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;file.&lt;/span&gt; &lt;span style="font-family:Cambria"&gt;private_data&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;字段中。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;lock&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;：自旋锁，用于保护该数据结构。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;mtx&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;：互斥量，主要用于多个&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_ctl&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;之间的并发，&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;以红黑树组织关注的&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_ctl&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;会修改红黑树，参见&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_ctl&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的实现。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;为什么有了一个自旋锁，还要搞一个互斥量？见最后一小结。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;wq&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;：&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_wait&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;使用的等待队列，在多线程程序中，我们可以在多个线程中对同一个&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;实例调用&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_wait&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;poll_wait&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;：这个域是比较让人费解的。这里说说我的理解：对于&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;socket fd&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，会将&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;对应的&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epitem&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;加入到&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;sock&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的等待队列，但是，对于&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epfd&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，没有&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;sock&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;对象，用&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;poll_wait&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;做等待队列，参见&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ep_eventpoll_poll&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;ovflist:&lt;/span&gt; &lt;span style="font-family:宋体;"&gt;主要是解决当内核在传输数据给用户空间&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;(ep_send_events_proc)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;时的锁&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;(eventpoll-&amp;gt;mtx)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，此时&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;就是将这个时候传递上来的事件保存到&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ovflist&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;2.1.2&lt;span style="font-family:宋体;Times New Roman&amp;quot;;Times New Roman&amp;quot;"&gt;、&lt;/span&gt;epitem&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;在&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;内部，每个关注的&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;都对应一个&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epitem&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;：&lt;/span&gt;&lt;/p&gt;  &lt;div style="border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt; background:silver"&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;epitem {&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* RB tree node used to link this structure to the eventpoll RB tree */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;rb_node rbn&lt;span style="color:#993300"&gt;; &lt;/span&gt;&lt;span style="color:green"&gt;///RB tree&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* List header used to link this structure to the eventpoll ready list */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;list_head rdllink&lt;span style="color:#993300"&gt;; &lt;/span&gt;&lt;span style="color:green"&gt;///ready list&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/*&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* Works together "struct eventpoll"-&amp;gt;ovflist in keeping the&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* single linked chain of items.&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*/&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;epitem &lt;span style="color:#993300"&gt;*&lt;/span&gt;next&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* The file descriptor information this item refers to */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;epoll_filefd ffd&lt;span style="color:#993300"&gt;; &lt;/span&gt;&lt;span style="color:green"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;文件描述符信息&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* Number of active wait queue attached to poll operations */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;int &lt;/span&gt;&lt;/strong&gt;nwait&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* List containing poll wait queues */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;list_head pwqlist&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* The "container" of this item */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;eventpoll &lt;span style="color:#993300"&gt;*&lt;/span&gt;ep&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* List header used to link this item to the "struct file" items list */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;list_head fllink&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* The structure that describe the interested events and the source fd */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;epoll_event event&lt;span style="color:#993300"&gt;; &lt;/span&gt;&lt;span style="color:green"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;关注的事件&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;};&lt;/p&gt;  &lt;/div&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;这个结构比较简单，没什么好说的。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;2.2&lt;span style="font-family:Cambria;"&gt;、核心函数&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;2.2.1&lt;span style="font-family:宋体;Times New Roman&amp;quot;;Times New Roman&amp;quot;"&gt;、&lt;/span&gt;epoll_ctl&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;当我们调用&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;epoll_create&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;创建一个&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;实例后，就可以调用&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_ctl&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;向&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;添加关注的&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;了。&lt;/span&gt;&lt;/p&gt;  &lt;div style="border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt; background:silver"&gt;  &lt;p&gt;SYSCALL_DEFINE4(epoll_ctl&lt;span style="color:#993300"&gt;, &lt;strong&gt;&lt;span style="color:maroon"&gt;int&lt;/span&gt;&lt;/strong&gt;&lt;span style="color:#993300"&gt;, &lt;/span&gt;epfd&lt;span style="color:#993300"&gt;, &lt;/span&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;int&lt;/span&gt;&lt;/strong&gt;&lt;span style="color:#993300"&gt;, &lt;/span&gt;op&lt;span style="color:#993300"&gt;, &lt;/span&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;int&lt;/span&gt;&lt;/strong&gt;&lt;span style="color:#993300"&gt;, &lt;/span&gt;fd&lt;span style="color:#993300"&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;epoll_event __user *, event)&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;{&lt;/p&gt;  &lt;p&gt;&amp;#8230;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ep &lt;span style="color:#993300"&gt;= &lt;/span&gt;file-&amp;gt;private_data&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;//&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;对互斥量加锁&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mutex_lock(&amp;amp;ep-&amp;gt;mtx);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/*&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* Try to lookup the file inside our RB tree, Since we grabbed "mtx"&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* above, we can be sure to be able to use the item looked up by&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* ep_find() till we release the mutex.&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*/&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; epi &lt;span style="color:#993300"&gt;= &lt;/span&gt;ep_find(ep&lt;span style="color:#993300"&gt;, &lt;/span&gt;tfile&lt;span style="color:#993300"&gt;, &lt;/span&gt;fd);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; error &lt;span style="color:#993300"&gt;= -&lt;/span&gt;EINVAL&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;switch &lt;/span&gt;(op) {&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;case &lt;/span&gt;EPOLL_CTL_ADD&lt;span style="color:#993300"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!epi) {&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; epds&lt;span style="color:#993300"&gt;.&lt;/span&gt;events |= POLLERR &lt;span style="color:#993300"&gt;| &lt;/span&gt;POLLHUP&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; error &lt;span style="color:#993300"&gt;= &lt;/span&gt;ep_insert(ep&lt;span style="color:#993300"&gt;, &amp;amp;&lt;/span&gt;epds&lt;span style="color:#993300"&gt;, &lt;/span&gt;tfile&lt;span style="color:#993300"&gt;, &lt;/span&gt;fd);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;span style="color:blue"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; error &lt;span style="color:#993300"&gt;= -&lt;/span&gt;EEXIST&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;break&lt;/span&gt;&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;case &lt;/span&gt;EPOLL_CTL_DEL&lt;span style="color:#993300"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (epi)&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; error &lt;span style="color:#993300"&gt;= &lt;/span&gt;ep_remove(ep&lt;span style="color:#993300"&gt;, &lt;/span&gt;epi);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; error &lt;span style="color:#993300"&gt;= -&lt;/span&gt;ENOENT&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;break&lt;/span&gt;&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;case &lt;/span&gt;EPOLL_CTL_MOD&lt;span style="color:#993300"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (epi) {&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; epds&lt;span style="color:#993300"&gt;.&lt;/span&gt;events |= POLLERR &lt;span style="color:#993300"&gt;| &lt;/span&gt;POLLHUP&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; error &lt;span style="color:#993300"&gt;= &lt;/span&gt;ep_modify(ep&lt;span style="color:#993300"&gt;, &lt;/span&gt;epi&lt;span style="color:#993300"&gt;, &amp;amp;&lt;/span&gt;epds);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;span style="color:blue"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; error &lt;span style="color:#993300"&gt;= -&lt;/span&gt;ENOENT&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;break&lt;/span&gt;&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mutex_unlock(&amp;amp;ep-&amp;gt;mtx);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;#8230;&lt;/p&gt;  &lt;p&gt;}&lt;/p&gt;  &lt;/div&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;ep_insert&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;：&lt;/span&gt;&lt;/p&gt;  &lt;div style="border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt; background:silver"&gt;  &lt;p&gt;&lt;span style="color:green"&gt;/* @tfile :target file&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;，即&lt;/span&gt;&lt;span style="color:green"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;对应的&lt;/span&gt;&lt;span style="color:green"&gt;file */&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;static int &lt;/span&gt;&lt;/strong&gt;ep_insert(&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;eventpoll &lt;span style="color:#993300"&gt;*&lt;/span&gt;ep&lt;span style="color:#993300"&gt;, &lt;/span&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;epoll_event &lt;span style="color:#993300"&gt;*&lt;/span&gt;event&lt;span style="color:#993300"&gt;,&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;file &lt;span style="color:#993300"&gt;*&lt;/span&gt;tfile&lt;span style="color:#993300"&gt;, &lt;/span&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;int &lt;/span&gt;&lt;/strong&gt;fd)&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;{&lt;/p&gt;  &lt;p&gt;&amp;#8230;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* Initialize the poll table using the queue callback */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; epq&lt;span style="color:#993300"&gt;.&lt;/span&gt;epi &lt;span style="color:#993300"&gt;= &lt;/span&gt;epi&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;//&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;设置&lt;/span&gt;&lt;span style="color:green"&gt;poll&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;中调用的回调函数&lt;/span&gt;&lt;span style="color:green"&gt;ep_ptable_queue_proc&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; init_poll_funcptr(&amp;amp;epq&lt;span style="color:#993300"&gt;.&lt;/span&gt;pt&lt;span style="color:#993300"&gt;, &lt;/span&gt;ep_ptable_queue_proc);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;调用底层文件系统的&lt;/span&gt;&lt;span style="color:green"&gt;poll&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;，对于&lt;/span&gt;&lt;span style="color:green"&gt;tcp socket&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;，为&lt;/span&gt;&lt;span style="color:green"&gt;sock_poll&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;，后者调用具体协议&lt;/span&gt;&lt;span style="color:green"&gt;(protocol-specific)&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;的&lt;/span&gt;&lt;span style="color:green"&gt;poll&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;，如&lt;/span&gt;&lt;span style="color:green"&gt;tcp_poll( ) */&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; revents &lt;span style="color:#993300"&gt;= &lt;/span&gt;tfile-&amp;gt;f_op-&amp;gt;poll(tfile&lt;span style="color:#993300"&gt;, &amp;amp;&lt;/span&gt;epq&lt;span style="color:#993300"&gt;.&lt;/span&gt;pt);&amp;nbsp;&lt;span style="color:green"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;参见&lt;/span&gt;&lt;span style="color:green"&gt;sock_poll&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;//&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;加入红黑树&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ep_rbtree_insert(ep&lt;span style="color:#993300"&gt;, &lt;/span&gt;epi);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* We have to drop the new item inside our item list to keep track of it */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; spin_lock_irqsave(&amp;amp;ep-&amp;gt;lock&lt;span style="color:#993300"&gt;, &lt;/span&gt;flags);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;如果文件已经&lt;/span&gt;&lt;span style="color:green"&gt;ready&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;，则加入到&lt;/span&gt;&lt;span style="color:green"&gt;ready list */&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ((revents &lt;span style="color:#993300"&gt;&amp;amp; &lt;/span&gt;event-&amp;gt;events) &lt;span style="color:#993300"&gt;&amp;amp;&amp;amp; !&lt;/span&gt;ep_is_linked(&amp;amp;epi-&amp;gt;rdllink)) {&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; list_add_tail(&amp;amp;epi-&amp;gt;rdllink&lt;span style="color:#993300"&gt;, &amp;amp;&lt;/span&gt;ep-&amp;gt;rdllist);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* Notify waiting tasks that events are available */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (waitqueue_active(&amp;amp;ep-&amp;gt;wq))&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; wake_up_locked(&amp;amp;ep-&amp;gt;wq); &lt;span style="color:green"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;唤醒等待进程&lt;/span&gt;&lt;span style="color:green"&gt;,&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;调用&lt;/span&gt;&lt;span style="color:green"&gt;epoll_wait&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;的进程&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (waitqueue_active(&amp;amp;ep-&amp;gt;poll_wait))&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pwake++;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; spin_unlock_irqrestore(&amp;amp;ep-&amp;gt;lock&lt;span style="color:#993300"&gt;, &lt;/span&gt;flags);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;#8230;&lt;/p&gt;  &lt;p&gt;}&lt;/p&gt;  &lt;/div&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;&amp;nbsp;ep_insert&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;主要将&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;添加到红黑树，然后在具体协议的&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;poll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，比如&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;tcp_poll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中，调用回调函数&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ep_ptable_queue_proc&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，最后检查&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;是否&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ready&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，如果&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ready&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，则将&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;加入到就绪队列，并唤醒等待进程。另外，值得一提的是在&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_ctl&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;和&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_wait&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中，对&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的就绪队列的访问都是由自旋锁&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;lock&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;保护。&lt;/span&gt;&lt;/p&gt;  &lt;div style="border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt; background:silver"&gt;  &lt;p&gt;&lt;span style="color:green"&gt;/* @file : target file&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;** @whead: fd&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;对应的&lt;/span&gt;&lt;span style="color:green"&gt;sock&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;的等待队列&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;*/&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;static void &lt;/span&gt;&lt;/strong&gt;ep_ptable_queue_proc(&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;file &lt;span style="color:#993300"&gt;*&lt;/span&gt;file&lt;span style="color:#993300"&gt;, &lt;/span&gt;wait_queue_head_t &lt;span style="color:#993300"&gt;*&lt;/span&gt;whead&lt;span style="color:#993300"&gt;,&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;poll_table &lt;span style="color:#993300"&gt;*&lt;/span&gt;pt)&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;{&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;epitem &lt;span style="color:#993300"&gt;*&lt;/span&gt;epi &lt;span style="color:#993300"&gt;= &lt;/span&gt;ep_item_from_epqueue(pt);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;eppoll_entry &lt;span style="color:#993300"&gt;*&lt;/span&gt;pwq&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (epi-&amp;gt;nwait &amp;gt;= 0 &lt;span style="color:#993300"&gt;&amp;amp;&amp;amp; &lt;/span&gt;(pwq &lt;span style="color:#993300"&gt;= &lt;/span&gt;kmem_cache_alloc(pwq_cache&lt;span style="color:#993300"&gt;, &lt;/span&gt;GFP_KERNEL))) {&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; init_waitqueue_func_entry(&amp;amp;pwq-&amp;gt;wait&lt;span style="color:#993300"&gt;, &lt;/span&gt;ep_poll_callback); &lt;span style="color:green"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;注册唤醒回&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;调函数&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pwq-&amp;gt;whead &lt;span style="color:#993300"&gt;= &lt;/span&gt;whead&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pwq-&amp;gt;base &lt;span style="color:#993300"&gt;= &lt;/span&gt;epi&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; add_wait_queue(whead&lt;span style="color:#993300"&gt;, &amp;amp;&lt;/span&gt;pwq-&amp;gt;wait);&amp;nbsp;&lt;span style="color:green"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;将&lt;/span&gt;&lt;span style="color:green"&gt;epitem&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;加到&lt;/span&gt;&lt;span style="color:green"&gt;sock&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;的等待队&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;列&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; list_add_tail(&amp;amp;pwq-&amp;gt;llink&lt;span style="color:#993300"&gt;, &amp;amp;&lt;/span&gt;epi-&amp;gt;pwqlist);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; epi-&amp;gt;nwait++;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;span style="color:blue"&gt;else &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* We have to signal that an error occurred */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; epi-&amp;gt;nwait &lt;span style="color:#993300"&gt;= -&lt;/span&gt;1&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;}&lt;/p&gt;  &lt;/div&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;ep_ptable_queue_proc&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;主要将&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_ctl&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;传进来的&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;封装成的&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epitem&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;添加到&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;target file&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;对应的&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;sock&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的等待队列。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;当&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;socket&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;收到数据时，内核协议栈会将其放到&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;sock&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的接收队列&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;sk_receive_queue&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，并调用&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;sk_data_ready&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;回调函数&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;(&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;如果用标准函数&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;sock_init_data&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;来初始化&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;sock&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;实例，通常是&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;sock_def_readable)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，唤醒等待队列，内核唤醒原语最终会调用这里注册的回调函数&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ep_poll_callback&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。&lt;/span&gt;&lt;/p&gt;  &lt;div style="border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt; background:silver"&gt;  &lt;p&gt;&lt;span style="color:green"&gt;//net/core/sock.c&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;static &lt;strong&gt;&lt;span style="color:maroon"&gt;void &lt;/span&gt;&lt;/strong&gt;sock_def_readable(&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;sock &lt;span style="color:#993300"&gt;*&lt;/span&gt;sk&lt;span style="color:#993300"&gt;, &lt;/span&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;int &lt;/span&gt;&lt;/strong&gt;len)&lt;/p&gt;  &lt;p&gt;{&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;socket_wq &lt;span style="color:#993300"&gt;*&lt;/span&gt;wq&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rcu_read_lock();&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; wq &lt;span style="color:#993300"&gt;= &lt;/span&gt;rcu_dereference(sk-&amp;gt;sk_wq);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (wq_has_sleeper(wq)) &lt;span style="color:green"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;检查&lt;/span&gt;&lt;span style="color:green"&gt;sock&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;的等待队列&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; wake_up_interruptible_sync_poll(&amp;amp;wq-&amp;gt;wait&lt;span style="color:#993300"&gt;, &lt;/span&gt;POLLIN &lt;span style="color:#993300"&gt;| &lt;/span&gt;POLLPRI &lt;span style="color:#993300"&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; POLLRDNORM &lt;span style="color:#993300"&gt;| &lt;/span&gt;POLLRDBAND); &lt;span style="color:green"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;唤醒&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sk_wake_async(sk&lt;span style="color:#993300"&gt;, &lt;/span&gt;SOCK_WAKE_WAITD&lt;span style="color:#993300"&gt;, &lt;/span&gt;POLL_IN);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rcu_read_unlock();&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;}&lt;/p&gt;  &lt;/div&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;下面来看看&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;ep_poll_callback&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;：&lt;/span&gt;&lt;/p&gt;  &lt;div style="border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt; background:silver"&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;static int &lt;/span&gt;&lt;/strong&gt;&lt;span&gt;ep_poll_callback(wait_queue_t &lt;span style="color:#993300"&gt;*&lt;/span&gt;wait&lt;span style="color:#993300"&gt;, &lt;/span&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;unsigned &lt;/span&gt;&lt;/strong&gt;mode&lt;span style="color:#993300"&gt;, &lt;/span&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;int &lt;/span&gt;&lt;/strong&gt;sync&lt;span style="color:#993300"&gt;, &lt;/span&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;void &lt;/span&gt;&lt;/strong&gt;&lt;span style="color:#993300"&gt;*&lt;/span&gt;key)&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;{&lt;/p&gt;  &lt;p&gt;&amp;#8230;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;epitem &lt;span style="color:#993300"&gt;*&lt;/span&gt;epi &lt;span style="color:#993300"&gt;= &lt;/span&gt;ep_item_from_wait(wait);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;eventpoll &lt;span style="color:#993300"&gt;*&lt;/span&gt;ep &lt;span style="color:#993300"&gt;= &lt;/span&gt;epi-&amp;gt;ep&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:red"&gt;spin_lock_irqsave(&amp;amp;ep-&amp;gt;lock&lt;/span&gt;&lt;span style="color:#993300"&gt;, &lt;/span&gt;&lt;span style="color:red"&gt;flags);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;//&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;如果只有&lt;/span&gt;&lt;span style="color:green"&gt;ET/ONESHOT&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;位设置&lt;/span&gt;&lt;span style="color:green"&gt;,&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;则不加入&lt;/span&gt;&lt;span style="color:green"&gt;ready list&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!(epi-&amp;gt;event&lt;span style="color:#993300"&gt;.&lt;/span&gt;events &lt;span style="color:#993300"&gt;&amp;amp; &lt;/span&gt;~EP_PRIVATE_BITS))&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;goto &lt;/span&gt;out_unlock&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;///check event&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (key &lt;span style="color:#993300"&gt;&amp;amp;&amp;amp; &lt;/span&gt;!((&lt;strong&gt;&lt;span style="color:maroon"&gt;unsigned long&lt;/span&gt;&lt;/strong&gt;) key &lt;span style="color:#993300"&gt;&amp;amp; &lt;/span&gt;epi-&amp;gt;event&lt;span style="color:#993300"&gt;.&lt;/span&gt;events))&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;goto &lt;/span&gt;out_unlock&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* If this file is already in the ready list we exit soon */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!ep_is_linked(&amp;amp;epi-&amp;gt;rdllink)) &lt;span style="color:green"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;加入&lt;/span&gt;&lt;span style="color:green"&gt;ready&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;链表&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; list_add_tail(&amp;amp;epi-&amp;gt;rdllink&lt;span style="color:#993300"&gt;, &amp;amp;&lt;/span&gt;ep-&amp;gt;rdllist);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/*&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* Wake up ( if active ) both the eventpoll wait list and the -&amp;gt;poll()&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* wait list.&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*/&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (waitqueue_active(&amp;amp;ep-&amp;gt;wq))&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; wake_up_locked(&amp;amp;ep-&amp;gt;wq); &lt;span style="color:green"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;唤醒等待进程&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (waitqueue_active(&amp;amp;ep-&amp;gt;poll_wait))&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pwake++;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;out_unlock&lt;span style="color:#993300"&gt;:&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; spin_unlock_irqrestore(&amp;amp;ep-&amp;gt;lock&lt;span style="color:#993300"&gt;, &lt;/span&gt;flags);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;#8230;&lt;/p&gt;  &lt;p&gt;}&lt;/p&gt;  &lt;/div&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;该函数将&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;加到&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;实例的&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;ready list&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，然后唤醒&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;实例的等待进程队列。注意红色部分，后面讨论&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;线程安全性的时候会再提到。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;2.2.2&lt;span style="font-family:宋体;Times New Roman&amp;quot;;Times New Roman&amp;quot;"&gt;、&lt;/span&gt;epoll_wait&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;当我们把关注的&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;添加到&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;环境后，就可以调用&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_wait&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;等待&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;上的事件发生了。&lt;/span&gt;&lt;/p&gt;  &lt;div style="border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt; background:silver"&gt;  &lt;p&gt;SYSCALL_DEFINE4(epoll_wait&lt;span style="color:#993300"&gt;, &lt;strong&gt;&lt;span style="color:maroon"&gt;int&lt;/span&gt;&lt;/strong&gt;&lt;span style="color:#993300"&gt;, &lt;/span&gt;epfd&lt;span style="color:#993300"&gt;, &lt;/span&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;epoll_event __user *, events&lt;span style="color:#993300"&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;int&lt;/span&gt;&lt;/strong&gt;&lt;span style="color:#993300"&gt;, &lt;/span&gt;maxevents&lt;span style="color:#993300"&gt;, &lt;/span&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;int&lt;/span&gt;&lt;/strong&gt;&lt;span style="color:#993300"&gt;, &lt;/span&gt;timeout)&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;{&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;file &lt;span style="color:#993300"&gt;*&lt;/span&gt;file&lt;span style="color:#993300"&gt;; &amp;nbsp;&lt;/span&gt;&lt;span style="color:green"&gt;///epfd file&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;eventpoll &lt;span style="color:#993300"&gt;*&lt;/span&gt;ep&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; file &lt;span style="color:#993300"&gt;= &lt;/span&gt;fget(epfd);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ep &lt;span style="color:#993300"&gt;= &lt;/span&gt;file-&amp;gt;private_data&lt;span style="color:#993300"&gt;; &lt;/span&gt;&lt;span style="color:green"&gt;///epoll&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;环境&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* Time to fish for events ... */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; error &lt;span style="color:#993300"&gt;= &lt;/span&gt;ep_poll(ep&lt;span style="color:#993300"&gt;, &lt;/span&gt;events&lt;span style="color:#993300"&gt;, &lt;/span&gt;maxevents&lt;span style="color:#993300"&gt;, &lt;/span&gt;timeout);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;#8230;&lt;/p&gt;  &lt;p&gt;}&lt;/p&gt;  &lt;/div&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;很简单，主要逻辑由&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ep_poll&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;完成：&lt;/span&gt;&lt;/p&gt;  &lt;div style="border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt; background:silver"&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;static int &lt;/span&gt;&lt;/strong&gt;ep_poll(&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;eventpoll &lt;span style="color:#993300"&gt;*&lt;/span&gt;ep&lt;span style="color:#993300"&gt;, &lt;/span&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;epoll_event __user &lt;span style="color:#993300"&gt;*&lt;/span&gt;events&lt;span style="color:#993300"&gt;,&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;int &lt;/span&gt;&lt;/strong&gt;maxevents&lt;span style="color:#993300"&gt;, &lt;/span&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;long &lt;/span&gt;&lt;/strong&gt;timeout)&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;{&lt;/p&gt;  &lt;p&gt;&amp;#8230;&lt;/p&gt;  &lt;p&gt;fetch_events&lt;span style="color:#993300"&gt;:&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; spin_lock_irqsave(&amp;amp;ep-&amp;gt;lock&lt;span style="color:#993300"&gt;, &lt;/span&gt;flags);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!ep_events_available(ep)) { &lt;span style="color:green"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;没有&lt;/span&gt;&lt;span style="color:green"&gt;ready event, sleep current process&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/*&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* We don't have any available event to return to the caller.&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* We need to sleep here, and we will be wake up by&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* ep_poll_callback() when events will become available.&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*/&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; init_waitqueue_entry(&amp;amp;wait&lt;span style="color:#993300"&gt;, &lt;/span&gt;current);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;///&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;将进程加入到&lt;/span&gt;&lt;span style="color:green"&gt;epoll&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;环境的等待队列&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; __add_wait_queue_exclusive(&amp;amp;ep-&amp;gt;wq&lt;span style="color:#993300"&gt;, &amp;amp;&lt;/span&gt;wait);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;for &lt;/span&gt;(;;) {&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/*&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* We don't want to sleep if the ep_poll_callback() sends us&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* a wakeup in between. That's why we set the task state&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* to TASK_INTERRUPTIBLE before doing the checks.&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*/&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set_current_state(TASK_INTERRUPTIBLE);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ep_events_available(ep) &lt;span style="color:#993300"&gt;|| &lt;/span&gt;timed_out) &lt;span style="color:green"&gt;///timeout==0, &lt;/span&gt;timed_out==1&lt;span style="color:#993300"&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;则&lt;/span&gt;&lt;span style="color:blue"&gt;break&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;break&lt;/span&gt;&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (signal_pending(current)) {&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; res &lt;span style="color:#993300"&gt;= -&lt;/span&gt;EINTR&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;break&lt;/span&gt;&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; spin_unlock_irqrestore(&amp;amp;ep-&amp;gt;lock&lt;span style="color:#993300"&gt;, &lt;/span&gt;flags);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!schedule_hrtimeout_range(to&lt;span style="color:#993300"&gt;, &lt;/span&gt;slack&lt;span style="color:#993300"&gt;, &lt;/span&gt;HRTIMER_MODE_ABS)) &lt;span style="color:green"&gt;///schedule&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; timed_out &lt;span style="color:#993300"&gt;= &lt;/span&gt;1&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; spin_lock_irqsave(&amp;amp;ep-&amp;gt;lock&lt;span style="color:#993300"&gt;, &lt;/span&gt;flags);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; __remove_wait_queue(&amp;amp;ep-&amp;gt;wq&lt;span style="color:#993300"&gt;, &amp;amp;&lt;/span&gt;wait);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set_current_state(TASK_RUNNING);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;check_events&lt;span style="color:#993300"&gt;:&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* Is it worth to try to dig for events ? */&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eavail &lt;span style="color:#993300"&gt;= &lt;/span&gt;ep_events_available(ep);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; spin_unlock_irqrestore(&amp;amp;ep-&amp;gt;lock&lt;span style="color:#993300"&gt;, &lt;/span&gt;flags);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/*&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* Try to transfer events to user space. In case we get 0 events and&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* there's still timeout left over, we go trying again in search of&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* more luck.&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*/&lt;/span&gt; &lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!res &lt;span style="color:#993300"&gt;&amp;amp;&amp;amp; &lt;/span&gt;eavail &lt;span style="color:#993300"&gt;&amp;amp;&amp;amp; &lt;/span&gt;&lt;span style="color:green"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;将事件拷贝到用户空间&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; !(res &lt;span style="color:#993300"&gt;= &lt;/span&gt;ep_send_events(ep&lt;span style="color:#993300"&gt;, &lt;/span&gt;events&lt;span style="color:#993300"&gt;, &lt;/span&gt;maxevents)) &lt;span style="color:#993300"&gt;&amp;amp;&amp;amp; !&lt;/span&gt;timed_out)&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;goto &lt;/span&gt;fetch_events&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;#8230;&lt;/p&gt;  &lt;p&gt;}&lt;/p&gt;  &lt;/div&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;&amp;nbsp;ep_poll&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的逻辑也非常简单，就是不断检查&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ready list&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，如果有&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ready fd&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，则将其拷贝到用户空间。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;注意&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;ep_poll&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;是调用&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;__add_wait_queue_exclusive&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;将当前进程加入到&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的等待队列的，所以，即使多个线程对同一个&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;调用&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_wait&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，也不会出现&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;thundering herd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;问题。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;最后来看一下&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;ep_send_events&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;函数，因为它与&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的几种模式：&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;LT&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;、&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ET&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;和&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ONESHOT&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;相关，理解了其实现，也就理解了&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;LT&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;、&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ET&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;与&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ONESHOT&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;2.2.3&lt;span style="font-family:宋体;Times New Roman&amp;quot;;Times New Roman&amp;quot;"&gt;、&lt;/span&gt;ep_send_events&lt;/strong&gt;&lt;/p&gt;  &lt;div style="border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt; background:silver"&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;static int &lt;/span&gt;&lt;/strong&gt;ep_send_events(&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;eventpoll &lt;span style="color:#993300"&gt;*&lt;/span&gt;ep&lt;span style="color:#993300"&gt;,&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;epoll_event __user &lt;span style="color:#993300"&gt;*&lt;/span&gt;events&lt;span style="color:#993300"&gt;, &lt;/span&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;int &lt;/span&gt;&lt;/strong&gt;maxevents)&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;{&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;ep_send_events_data esed&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; esed&lt;span style="color:#993300"&gt;.&lt;/span&gt;maxevents &lt;span style="color:#993300"&gt;= &lt;/span&gt;maxevents&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; esed&lt;span style="color:#993300"&gt;.&lt;/span&gt;events &lt;span style="color:#993300"&gt;= &lt;/span&gt;events&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;处理&lt;/span&gt;&lt;span style="color:green"&gt;ready list&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;return &lt;/span&gt;ep_scan_ready_list(ep&lt;span style="color:#993300"&gt;, &lt;/span&gt;ep_send_events_proc&lt;span style="color:#993300"&gt;, &amp;amp;&lt;/span&gt;esed);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;}&lt;/p&gt;  &lt;/div&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;主要逻辑是在回调函数&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ep_send_events_proc&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中完成的。&lt;/span&gt;&lt;/p&gt;  &lt;table style="border-collapse:collapse;border:none;" border="1" cellpadding="0" cellspacing="0"&gt;  &lt;tbody&gt;&lt;tr&gt;   &lt;td style="width:426.1pt;border:solid windowtext 1.0pt;background:#E6E6E6;padding:0cm 5.4pt 0cm 5.4pt" valign="top" width="568"&gt;   &lt;div style="border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;   background:silver"&gt;   &lt;p&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;static int &lt;/span&gt;&lt;/strong&gt;ep_send_events_proc(&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;eventpoll   &lt;span style="color:#993300"&gt;*&lt;/span&gt;ep&lt;span style="color:#993300"&gt;, &lt;/span&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;list_head   &lt;span style="color:#993300"&gt;*&lt;/span&gt;head&lt;span style="color:#993300"&gt;,&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;void &lt;/span&gt;&lt;/strong&gt;&lt;span style="color:#993300"&gt;*&lt;/span&gt;priv)&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;{&lt;/p&gt;   &lt;p&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;ep_send_events_data &lt;span style="color:#993300"&gt;*esed &lt;span style="color:#993300"&gt;= &lt;/span&gt;priv&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;int &lt;/span&gt;&lt;/strong&gt;eventcnt&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;unsigned int &lt;/span&gt;&lt;/strong&gt;revents&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;epitem   &lt;span style="color:#993300"&gt;*&lt;/span&gt;epi&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;epoll_event   __user &lt;span style="color:#993300"&gt;*&lt;/span&gt;uevent&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&amp;nbsp;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/*&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* We can loop without   lock because we are passed a task private list.&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* Items cannot vanish   during the loop because ep_scan_ready_list() is&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* holding   "mtx" during this call.&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*/&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;for &lt;/span&gt;(eventcnt &lt;span style="color:#993300"&gt;= &lt;/span&gt;0&lt;span style="color:#993300"&gt;, &lt;/span&gt;uevent &lt;span style="color:#993300"&gt;= &lt;/span&gt;esed-&amp;gt;events&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#993300"&gt;!&lt;/span&gt;list_empty(head)   &lt;span style="color:#993300"&gt;&amp;amp;&amp;amp; &lt;/span&gt;eventcnt &amp;lt;   esed-&amp;gt;maxevents;) {&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; epi   &lt;span style="color:#993300"&gt;= &lt;/span&gt;list_first_entry(head&lt;span style="color:#993300"&gt;, &lt;/span&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;epitem&lt;span style="color:#993300"&gt;, &lt;/span&gt;rdllink);&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&amp;nbsp;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; list_del_init(&amp;amp;epi-&amp;gt;rdllink);   &lt;span style="color:green"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;删除一个&lt;/span&gt;&lt;span style="color:green"&gt;epitem&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;检查事件&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; revents   &lt;span style="color:#993300"&gt;= &lt;/span&gt;epi-&amp;gt;ffd&lt;span style="color:#993300"&gt;.&lt;/span&gt;file-&amp;gt;f_op-&amp;gt;poll(epi-&amp;gt;ffd&lt;span style="color:#993300"&gt;.&lt;/span&gt;file&lt;span style="color:#993300"&gt;, &lt;/span&gt;&lt;span style="color:blue"&gt;NULL&lt;/span&gt;) &lt;span style="color:#993300"&gt;&amp;amp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; epi-&amp;gt;event&lt;span style="color:#993300"&gt;.&lt;/span&gt;events&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&amp;nbsp;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/*&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* If the event   mask intersect the caller-requested one,&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* deliver the   event to userspace. Again, ep_scan_ready_list()&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* is holding   "mtx", so no operations coming from userspace&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* can change   the item.&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*/&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if   (revents) {&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if   (__put_user(revents&lt;span style="color:#993300"&gt;, &amp;amp;&lt;/span&gt;uevent-&amp;gt;events)   &lt;span style="color:#993300"&gt;||&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; __put_user(epi-&amp;gt;event&lt;span style="color:#993300"&gt;.&lt;/span&gt;data&lt;span style="color:#993300"&gt;, &amp;amp;&lt;/span&gt;uevent-&amp;gt;data))   {&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; list_add(&amp;amp;epi-&amp;gt;rdllink&lt;span style="color:#993300"&gt;, &lt;/span&gt;head); &lt;span style="color:green"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;加入到输出队列&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;return &lt;/span&gt;eventcnt ? eventcnt &lt;span style="color:#993300"&gt;:   -&lt;/span&gt;EFAULT&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eventcnt++;&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; uevent++;&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if   (epi-&amp;gt;event&lt;span style="color:#993300"&gt;.&lt;/span&gt;events &lt;span style="color:#993300"&gt;&amp;amp; &lt;/span&gt;EPOLLONESHOT)&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:green"&gt;///take care,&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;只设置&lt;/span&gt;&lt;span style="color:green"&gt;EPOLLET/EPOLLONESHOT,&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;参见&lt;/span&gt;&lt;span style="font-family:Cambria;   color:green"&gt;ep_poll_callback&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;epi-&amp;gt;event&lt;span style="color:#993300"&gt;.&lt;/span&gt;events   &amp;amp;= EP_PRIVATE_BITS&lt;span style="color:#993300"&gt;; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;else &lt;/span&gt;if (!(epi-&amp;gt;event&lt;span style="color:#993300"&gt;.&lt;/span&gt;events   &lt;span style="color:#993300"&gt;&amp;amp; &lt;/span&gt;EPOLLET)) { &lt;span style="color:green"&gt;//LT&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;模式&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/*&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* If this file has been added with Level&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* Trigger mode, we need to insert back   inside&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* the ready list, so that the next call to&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* epoll_wait() will check again the events&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* availability. At this point, no one can   insert&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* into ep-&amp;gt;rdllist besides us. The   epoll_ctl()&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* callers are locked out by&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* ep_scan_ready_list() holding   "mtx" and the&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* poll callback will queue them in   ep-&amp;gt;ovflist.&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*/&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; list_add_tail(&amp;amp;epi-&amp;gt;rdllink&lt;span style="color:#993300"&gt;, &amp;amp;&lt;/span&gt;ep-&amp;gt;rdllist); &lt;span style="color:green"&gt;//LT&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;模式&lt;/span&gt;&lt;span style="color:green"&gt;,&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;重新加入到&lt;/span&gt;ready list&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&amp;nbsp;&lt;/p&gt;   &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;return &lt;/span&gt;eventcnt&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;&lt;span style="color:#993300"&gt;}&lt;/span&gt;&lt;/p&gt;   &lt;/div&gt;   &lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;LT&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;：&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;Level Triggered&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，水平触发是&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的默认工作模式，当&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;上有事件发生，内核除了把事件上报给用户，还把&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;重新加到就绪队列中，所以直到收集事件时没有事件发生，该&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;才从&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的就绪队列中移除。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;例如：&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;socket fd&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;可读，如果数据并没有读完，则接下来每次&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_wait&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;都会返回该&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;可读，直到有一次收集事件失败，即&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;socket&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;不可读。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;ET:&lt;/span&gt; &lt;span style="font-family:Cambria"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Edge Triggered&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，边缘触发，相比&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;LT&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ET&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;收集完事件后不会把&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;重新加入就绪队列。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;如果&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;可读，&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;上报有事件发生，该&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;也从就绪队列中移除了，无论数据有没有读完。该&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;只有在下次事件发生并在回调函数&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ep_poll_callback&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中被加入就绪队列。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;ONESHOT: &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;顾名思义，如果&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;有事件发生，只会触发一次。从&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ep_send_events_pro&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的实现可以看到，对于&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;EPOLLONESHOT&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，会将其它事件位全部清掉。这样，以后&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ep_poll_callback(&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;参见其实现&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;将不会将该&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;加入&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ready list&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，即使有事件发生，直到用户再一次通过&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;EPOLL_CTL_MOD&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;重新设置&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。所以，对于&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ONESHOT&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，如果有事件发生，每次&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;EPOLL_CTL_MOD&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;只会上报一次。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="font-size:14.0pt; font-family:宋体;Times New Roman&amp;quot;;"&gt;第三部分&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;&lt;strong&gt;&lt;span style="font-size:14.0pt; font-family:宋体;Times New Roman&amp;quot;;"&gt;问题&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;3&lt;span style="font-family:宋体;Times New Roman&amp;quot;;Times New Roman&amp;quot;"&gt;、&lt;/span&gt;epoll&lt;span style="font-family:宋体;Times New Roman&amp;quot;;Times New Roman&amp;quot;"&gt;为什么比&lt;/span&gt;poll&lt;span style="font-family:宋体;Times New Roman&amp;quot;;Times New Roman&amp;quot;"&gt;高效&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;先看看&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;poll&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;的实现：&lt;/span&gt;&lt;/p&gt;  &lt;div style="border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt; background:silver"&gt;  &lt;p&gt;&lt;span style="color:green"&gt;//fs/select.c&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;SYSCALL_DEFINE3(poll&lt;span style="color:#993300"&gt;, &lt;/span&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;pollfd __user *, ufds&lt;span style="color:#993300"&gt;, &lt;/span&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;unsigned int&lt;/span&gt;&lt;/strong&gt;&lt;span style="color:#993300"&gt;, &lt;/span&gt;nfds&lt;span style="color:#993300"&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;long&lt;/span&gt;&lt;/strong&gt;&lt;span style="color:#993300"&gt;, &lt;/span&gt;timeout_msecs)&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;{&lt;/p&gt;  &lt;p&gt;&amp;#8230;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret &lt;span style="color:#993300"&gt;= &lt;/span&gt;do_sys_poll(ufds&lt;span style="color:#993300"&gt;, &lt;/span&gt;nfds&lt;span style="color:#993300"&gt;, &lt;/span&gt;to);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;#8230;&lt;/p&gt;  &lt;p&gt;}&lt;/p&gt;  &lt;/div&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;主要逻辑在&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;do_sys_poll&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;完成：&lt;/span&gt;&lt;/p&gt;  &lt;div style="border:solid windowtext 1.0pt;padding:1.0pt 4.0pt 1.0pt 4.0pt; background:silver"&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;int &lt;/span&gt;&lt;/strong&gt;&lt;span style="color:blue"&gt;do&lt;/span&gt;_sys_poll(&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;pollfd __user &lt;span style="color:#993300"&gt;*&lt;/span&gt;ufds&lt;span style="color:#993300"&gt;, &lt;/span&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;unsigned int &lt;/span&gt;&lt;/strong&gt;nfds&lt;span style="color:#993300"&gt;,&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;timespec &lt;span style="color:#993300"&gt;*&lt;/span&gt;end_time)&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;{&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;poll_wqueues table&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;int &lt;/span&gt;&lt;/strong&gt;err &lt;span style="color:#993300"&gt;= -&lt;/span&gt;EFAULT&lt;span style="color:#993300"&gt;, &lt;/span&gt;fdcount&lt;span style="color:#993300"&gt;, &lt;/span&gt;len&lt;span style="color:#993300"&gt;, &lt;/span&gt;size&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;/* Allocate small arguments on the stack to save memory and be&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; faster - use &lt;strong&gt;long &lt;/strong&gt;to make sure the buffer is aligned properly&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; on 64 bit archs to avoid unaligned access */&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;long &lt;/span&gt;&lt;/strong&gt;stack_pps[POLL_STACK_ALLOC&lt;span style="color:#993300"&gt;/&lt;/span&gt;&lt;span style="color:blue"&gt;sizeof&lt;/span&gt;(&lt;strong&gt;&lt;span style="color:maroon"&gt;long&lt;/span&gt;&lt;/strong&gt;)];&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;poll_list &lt;span style="color:#993300"&gt;*&lt;/span&gt;&lt;strong&gt;&lt;span style="color:maroon"&gt;const &lt;/span&gt;&lt;/strong&gt;head &lt;span style="color:#993300"&gt;= &lt;/span&gt;(&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;poll_list *)stack_pps&lt;span style="color:#993300"&gt;; &lt;/span&gt;&lt;span style="color:green"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;先使用栈上的空间&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;poll_list &lt;span style="color:#993300"&gt;*&lt;/span&gt;walk &lt;span style="color:#993300"&gt;= &lt;/span&gt;head&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;unsigned long &lt;/span&gt;&lt;/strong&gt;todo &lt;span style="color:#993300"&gt;= &lt;/span&gt;nfds&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (nfds &amp;gt; rlimit(RLIMIT_NOFILE))&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;return &lt;/span&gt;&lt;span style="color:#993300"&gt;-&lt;/span&gt;EINVAL&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; len &lt;span style="color:#993300"&gt;= &lt;/span&gt;min_t(&lt;strong&gt;&lt;span style="color:maroon"&gt;unsigned int&lt;/span&gt;&lt;/strong&gt;&lt;span style="color:#993300"&gt;, &lt;/span&gt;nfds&lt;span style="color:#993300"&gt;, &lt;/span&gt;N_STACK_PPS);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;for &lt;/span&gt;(;;) {&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; walk-&amp;gt;next &lt;span style="color:#993300"&gt;= &lt;/span&gt;&lt;span style="color:blue"&gt;NULL&lt;/span&gt;&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; walk-&amp;gt;len &lt;span style="color:#993300"&gt;= &lt;/span&gt;len&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!len)&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;break&lt;/span&gt;&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;///1.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;将用户空间的描述符拷贝到内核&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (copy_from_user(walk-&amp;gt;entries&lt;span style="color:#993300"&gt;, &lt;/span&gt;ufds &lt;span style="color:#993300"&gt;+ &lt;/span&gt;nfds&lt;span style="color:#993300"&gt;-&lt;/span&gt;todo&lt;span style="color:#993300"&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;sizeof&lt;/span&gt;(&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;pollfd) &lt;span style="color:#993300"&gt;* &lt;/span&gt;walk-&amp;gt;len))&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;goto &lt;/span&gt;out_fds&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; todo -= walk-&amp;gt;len&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!todo)&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;break&lt;/span&gt;&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;如果栈上空间不够&lt;/span&gt;&lt;span style="color:green"&gt;,&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;则调用&lt;/span&gt;&lt;span style="color:green"&gt;kmalloc&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;分配空间存储描述符信息&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; len &lt;span style="color:#993300"&gt;= &lt;/span&gt;min(todo&lt;span style="color:#993300"&gt;, &lt;/span&gt;POLLFD_PER_PAGE);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; size &lt;span style="color:#993300"&gt;= &lt;/span&gt;&lt;span style="color:blue"&gt;sizeof&lt;/span&gt;(&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;poll_list) &lt;span style="color:#993300"&gt;+ &lt;/span&gt;&lt;span style="color:blue"&gt;sizeof&lt;/span&gt;(&lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;pollfd) &lt;span style="color:#993300"&gt;* &lt;/span&gt;len&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; walk &lt;span style="color:#993300"&gt;= &lt;/span&gt;walk-&amp;gt;next &lt;span style="color:#993300"&gt;= &lt;/span&gt;kmalloc(size&lt;span style="color:#993300"&gt;, &lt;/span&gt;GFP_KERNEL);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!walk) {&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; err &lt;span style="color:#993300"&gt;= -&lt;/span&gt;ENOMEM&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;goto &lt;/span&gt;out_fds&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;设置&lt;/span&gt;&lt;span style="color:green"&gt;poll&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;的回调函数&lt;/span&gt;&lt;span style="color:green"&gt;,&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;与&lt;/span&gt;&lt;span style="color:green"&gt;epoll&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;类似&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; poll_initwait(&amp;amp;table);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color:green"&gt;///2.poll&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;所有描述符&lt;/span&gt;&lt;span style="color:green"&gt;,&lt;/span&gt;&lt;span style="font-family:宋体; color:green"&gt;是否有事件发生&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fdcount &lt;span style="color:#993300"&gt;= &lt;/span&gt;&lt;span style="color:blue"&gt;do&lt;/span&gt;_poll(nfds&lt;span style="color:#993300"&gt;, &lt;/span&gt;head&lt;span style="color:#993300"&gt;, &amp;amp;&lt;/span&gt;table&lt;span style="color:#993300"&gt;, &lt;/span&gt;end_time); &lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; poll_freewait(&amp;amp;table);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;for &lt;/span&gt;(walk &lt;span style="color:#993300"&gt;= &lt;/span&gt;head&lt;span style="color:#993300"&gt;; &lt;/span&gt;walk&lt;span style="color:#993300"&gt;; &lt;/span&gt;walk &lt;span style="color:#993300"&gt;= &lt;/span&gt;walk-&amp;gt;next) {&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;struct &lt;/span&gt;&lt;/strong&gt;pollfd &lt;span style="color:#993300"&gt;*&lt;/span&gt;fds &lt;span style="color:#993300"&gt;= &lt;/span&gt;walk-&amp;gt;entries&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="color:maroon"&gt;int &lt;/span&gt;&lt;/strong&gt;j&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:green"&gt;///3.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;color:green"&gt;设置相应文件描述发生的事件&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;for &lt;/span&gt;(j &lt;span style="color:#993300"&gt;= &lt;/span&gt;0&lt;span style="color:#993300"&gt;; &lt;/span&gt;j &amp;lt; walk-&amp;gt;len&lt;span style="color:#993300"&gt;; &lt;/span&gt;j++, ufds++)&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (__put_user(fds[j].revents&lt;span style="color:#993300"&gt;, &amp;amp;&lt;/span&gt;ufds-&amp;gt;revents))&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue"&gt;goto &lt;/span&gt;out_fds&lt;span style="color:#993300"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;span&gt;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;#8230;&lt;/p&gt;  &lt;p&gt;}&lt;/p&gt;  &lt;/div&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;从上面的代码可以看出，&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;poll&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;至少有三个原因导致它比&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;效率低：&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;(1)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;每次调用都要将用户空间的所有描述符信息拷贝到内核；&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;(2)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;与&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;不同，&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;poll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;内部没一个&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ready list&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，所以，每次都需要检查所有的描述符；&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;(3)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;遍历所有的描述符，设置发生的事件。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;当&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;fd&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;数量较多时，比如支持上万连接的高并发的&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;server&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，这些遍历操作会成为性能的致命杀手。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;4&lt;span style="font-family:宋体;Times New Roman&amp;quot;;Times New Roman&amp;quot;"&gt;、&lt;/span&gt;epoll&lt;span style="font-family:宋体;Times New Roman&amp;quot;;Times New Roman&amp;quot;"&gt;线程安全性&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;Times New Roman&amp;quot;"&gt;考虑两种情况：一是两个线程对同一个&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family: 宋体;Times New Roman&amp;quot;"&gt;调用&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_ctl&lt;/span&gt;&lt;span style="font-family: 宋体;Times New Roman&amp;quot;"&gt;；二是&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;A&lt;/span&gt;&lt;span style="font-family:宋体;Times New Roman&amp;quot;"&gt;线程对&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family: 宋体;Times New Roman&amp;quot;"&gt;调用&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_wait&lt;/span&gt;&lt;span style="font-family: 宋体;Times New Roman&amp;quot;"&gt;，同时线程&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;B&lt;/span&gt;&lt;span style="font-family:宋体;Times New Roman&amp;quot;"&gt;调用&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_ctl&lt;/span&gt;&lt;span style="font-family: 宋体;Times New Roman&amp;quot;"&gt;。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family: Cambria;"&gt;&lt;span&gt;(1)&lt;span style="font:7.0pt &amp;quot;Times New Roman&amp;quot;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;从第&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;2&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;节的&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;实现可以看到，&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_ctl&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;会修改内部红黑树，而且同时涉及到内存分配，所以它们之间通过互斥量保证线程性安全性。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family: Cambria;"&gt;&lt;span&gt;(2)&lt;span style="font:7.0pt &amp;quot;Times New Roman&amp;quot;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;另外，&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_wait&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;与&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_wait&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，或者&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_wait&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;与&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_ctl&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;之间，涉及到对&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;内部&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;ready list&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;的访问，而且时间很短，没有其它复杂逻辑。所以用自旋锁保护。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;综上，&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;是线程安全的。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;在&lt;/span&gt;&lt;span style="font-family: Cambria"&gt;Memcached&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;中，每个线程都有一个&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll loop&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，主线程&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;(&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;处理&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;accept)&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;收到一个连接，会丢到工作线程的&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll loop&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;中，它先将连接对象&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;CQ_ITEM&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;加入工作线程的队列，然后通过管道来通知工作线程。但是，由于两个线程需要访问连接对象队列，所以，使用了锁来保护。实际上，如果在主线程中直接对工作线程调用&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_ctl&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，是没有问题的，这样，我们就可以做一些工作&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;(&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;比如利用&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll_event&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;数据结构&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;，从而做到多个线程间无锁编程&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;(&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;这里的无锁是指用户态无锁，但内核仍然会有锁&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;)&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;。注意，这里只针对&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;epoll&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;，不适用于其它模型。&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:宋体;"&gt;主要参考&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;1. Kernel 3.0 sourcode&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;2. Libevent 1.4.13 sourcecode&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;3. Memcached 1.4.5 sourcecode&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;4. Haproxy 1.4.8 sourcecode&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;5. Nginx 0.8.28 sourcecode&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;6. &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;《&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;Half Sync/Half Async&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;》&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;7. &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;《&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;Leader/Followers:A Design Pattern for Efﬁcient Multi-threaded I/O Demultiplexing and Dispatching&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;》&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;8. &lt;/span&gt;&lt;span style="font-family:宋体;"&gt;《&lt;/span&gt;&lt;span style="font-family:Cambria"&gt;Understanding Linux Network Internals&lt;/span&gt;&lt;span style="font-family:宋体;"&gt;》&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;9.&amp;nbsp;http://lkml.indiana.edu/hypermail/linux/kernel/0106.2/0405.html&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="font-family:Cambria"&gt;&lt;/span&gt;&lt;span style="font-family: 宋体;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div id="AllanboltSignature"&gt;  &lt;p id="PSignature"&gt;&lt;br /&gt;作者：MrDB &lt;br /&gt;出处：&lt;a href="http://www.cnblogs.com/hustcat/" target="_blank"&gt;http://www.cnblogs.com/hustcat/&lt;/a&gt; &lt;br /&gt;本文版权归作者和博客园共有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。 &lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/hustcat/aggbug/2319249.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hustcat/archive/2012/01/11/2319249.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hustcat/archive/2011/12/29/2306588.html</id><title type="text">一个由string使用不当产生的问题</title><summary type="text">一个由string使用不当产生的问题</summary><published>2011-12-29T11:37:00Z</published><updated>2011-12-29T11:37:00Z</updated><author><name>MrDB</name><uri>http://www.cnblogs.com/hustcat/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hustcat/archive/2011/12/29/2306588.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hustcat/archive/2011/12/29/2306588.html"/><content type="html">&lt;p&gt;今天因不正确的使用std::string，产生一个很难发觉的问题，搞了许久，mark一下。 原代码大概如下：&lt;/p&gt;&lt;p&gt;void func(char *buf, int len){&lt;/p&gt;&lt;p&gt;string s;&lt;/p&gt;&lt;p&gt;s.reserve(len);&lt;/p&gt;&lt;p&gt;memcpy((char *)&amp;amp;s[0], buf, len));&lt;/p&gt;&lt;p&gt;string t(s, 0, len);&lt;/p&gt;&lt;p&gt;}&lt;/p&gt;&lt;p&gt;发现t中的数据始终为空。 最后才明白，reserve函数没有更改string的size，也就是说s.size()==0， 后面其它字符串通过string的方法从s获取数据，由于size为零，都不能真正拷贝数据。 解决方法很简单，将reserve换成resize即可。可参考resize的源码：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;    &lt;span style="color: #800080;"&gt;610&lt;/span&gt;   template&amp;lt;typename _CharT, typename _Traits, typename _Alloc&amp;gt;&lt;br /&gt;    &lt;span style="color: #800080;"&gt;611&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #800080;"&gt;612&lt;/span&gt;     basic_string&amp;lt;_CharT, _Traits, _Alloc&amp;gt;::&lt;br /&gt;    &lt;span style="color: #800080;"&gt;613&lt;/span&gt;     resize(size_type __n, _CharT __c)&lt;br /&gt;    &lt;span style="color: #800080;"&gt;614&lt;/span&gt;     {&lt;br /&gt;    &lt;span style="color: #800080;"&gt;615&lt;/span&gt;       &lt;span style="color: #0000ff;"&gt;const&lt;/span&gt; size_type __size = &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;-&amp;gt;size();&lt;br /&gt;    &lt;span style="color: #800080;"&gt;616&lt;/span&gt;       _M_check_length(__size, __n, &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;basic_string::resize&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;    &lt;span style="color: #800080;"&gt;617&lt;/span&gt;       &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (__size &amp;lt; __n)&lt;br /&gt;    &lt;span style="color: #800080;"&gt;618&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;-&amp;gt;append(__n - __size, __c);&lt;br /&gt;    &lt;span style="color: #800080;"&gt;619&lt;/span&gt;       &lt;span style="color: #0000ff;"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (__n &amp;lt; __size)&lt;br /&gt;    &lt;span style="color: #800080;"&gt;620&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;-&amp;gt;erase(__n);&lt;br /&gt;    &lt;span style="color: #800080;"&gt;621&lt;/span&gt;       &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; else nothing (in particular, avoid calling _M_mutate() unnecessarily.)&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;    &lt;span style="color: #800080;"&gt;622&lt;/span&gt;     } &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; /usr/include/c++/4.1.0/bits/basic_string.tcc&lt;/span&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/hustcat/aggbug/2306588.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hustcat/archive/2011/12/29/2306588.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hustcat/archive/2011/10/27/2226995.html</id><title type="text">从free到page cache</title><summary type="text">我们经常用free查看服务器的内存使用情况，而free中的输出却有些让人困惑，这里就探讨一下free。</summary><published>2011-10-27T12:32:00Z</published><updated>2011-10-27T12:32:00Z</updated><author><name>MrDB</name><uri>http://www.cnblogs.com/hustcat/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hustcat/archive/2011/10/27/2226995.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hustcat/archive/2011/10/27/2226995.html"/><content type="html">&lt;h3 style="margin: 13pt 0cm"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;font size="3"&gt;Free&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"&gt;我们经常用&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font face="Times New Roman"&gt;free&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"&gt;查看服务器的内存使用情况，而&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font face="Times New Roman"&gt;free&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"&gt;中的输出却有些让人困惑，如下：&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"&gt;&lt;div align="center"&gt;&lt;img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/hustcat/2011/cache1.png" width="750" height="85" /&gt;&lt;/div&gt;&lt;/span&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" align="center"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"&gt;图&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font face="Times New Roman"&gt;1-1&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;先看看各个数字的意义以及如何计算得到：&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;free&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;命令输出的第二行&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;(Mem)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;：这行分别显示了物理内存的总量&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;(total)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;、已使用的&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt; (used)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;、空闲的&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;(free)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;、共享的&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;(shared)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;、&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;(buffer&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;大小&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;、&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt; cache(&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;的大小&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;的内存。我们知道&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;Total&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;、&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;free&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;、&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;buffers&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;、&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;cached&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;这几个字段是从&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;/proc/meminfo&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;中获取的，而&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;used = total &lt;/span&gt;&lt;span style="mso-ascii-font-family: Cambria" lang="EN-US"&gt;&lt;font face="Times New Roman"&gt;&amp;#8211;&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt; free&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;。&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;Share&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;列已经过时，忽略&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;见参考&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;free&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;命令输出的第三行&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;(-/+ buffers/cache)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;：&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;它显示的第一个值&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;used&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;：&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;548840&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;，这个值表示系统本身使用的内存总量，即除去&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;buffer/cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;，等于&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;Mem&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;行&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;used&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;列&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt; - Mem&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;行&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffers&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;列&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt; - Mem&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;行&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;cached&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;列。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;它显示的第二个值&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;free&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;：&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;1417380&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;，这个值表示系统当前可用内存，它等于&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;Mem&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;行&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;total&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;列&amp;#8212;&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;used&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;，也等于&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;Mem&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;行&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;free&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;列&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt; + Mem&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;行&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffers&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;列&lt;/span&gt;&lt;span style="font-family: Cambria"&gt; &lt;span lang="EN-US"&gt;+ Mem&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;行&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;cached&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;列。&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;free&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;命令输出的第四行&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;(Swap) &lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;这行显示交换内存的总量、已使用量、&lt;/span&gt;&lt;span style="font-family: Cambria"&gt; &lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;空闲量。&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;我们都知道&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;free&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;是从&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;/proc/meminfo&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;中读取相关的数据的。&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;&lt;o:p&gt;&lt;div align="center"&gt;&lt;img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/hustcat/2011/cache2.png" width="420" height="134" /&gt;&lt;/div&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal" align="center"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" align="center"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"&gt;图&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font face="Times New Roman"&gt;1-2&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"&gt;来看看&lt;/span&gt;&lt;span lang="EN-US"&gt;&lt;font face="Times New Roman"&gt;/proc/meminfo&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"&gt;的相关实现：&lt;/span&gt;&lt;/p&gt;&lt;table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" class="MsoTableGrid" border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes"&gt;&lt;td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt;background: #cccccc; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm; mso-border-alt: solid windowtext .5pt" valign="top" width="568"&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;// proc_misc.c&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;static int meminfo_read_proc(char *page, char **start, off_t off,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 4"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/span&gt;int count, int *eof, void *data)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&amp;#8230;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;struct sysinfo i;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;si_meminfo(&amp;amp;i); //&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;统计&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;memory&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;的使用情况&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;si_swapinfo(&amp;amp;i); //&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;统计&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;swap&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;的使用情况&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&amp;#8230;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;len = sprintf(page,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;"MemTotal:&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;%8lu kB\n"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;"MemFree:&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;%8lu kB\n"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;"Buffers:&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;%8lu kB\n"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;"Cached:&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;%8lu kB\n"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;"SwapCached:&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;%8lu kB\n"&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&amp;#8230;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;K(i.totalram),&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;K(i.freeram),&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;K(i.bufferram),&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;K(get_page_cache_size()-total_swapcache_pages-i.bufferram),&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;K(total_swapcache_pages),&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&amp;#8230;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;struct sysinfo {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;long uptime;&lt;span style="mso-tab-count: 3"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* Seconds since boot */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;unsigned long loads[3];&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* 1, 5, and 15 minute load averages */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;unsigned long totalram;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/*&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;总的页框数&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;,Total usable main memory size */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;unsigned long freeram;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* Available memory size */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;unsigned long sharedram;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* Amount of shared memory */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;unsigned long bufferram;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* Memory used by buffers */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;unsigned long totalswap;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* Total swap space size */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;unsigned long freeswap;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* swap space still available */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;unsigned short procs;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* Number of current processes */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;unsigned short pad;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* explicit padding for m68k */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;unsigned long totalhigh;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* Total high memory size */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;unsigned long freehigh;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* Available high memory size */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;unsigned int mem_unit;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* Memory unit size in bytes */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;char _f[20-2*sizeof(long)-sizeof(int)];&lt;span style="mso-tab-count: 1"&gt; &lt;/span&gt;/* Padding: libc5 uses this.. */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;};&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;图中，&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;Buffers&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;对应&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;sysinfo.bufferram&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;，内核中以页框为单位，通过宏&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;K&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;转化成以&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;KB&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;为单位输出。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" class="MsoTableGrid" border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes"&gt;&lt;td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt;background: #cccccc; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm; mso-border-alt: solid windowtext .5pt" valign="top" width="568"&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;void si_meminfo(struct sysinfo *val)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;val-&amp;gt;totalram = totalram_pages;//&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;总的页框数&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;val-&amp;gt;sharedram = 0;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;val-&amp;gt;freeram = nr_free_pages();//&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;计算空闲页框数&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: blue"&gt;val-&amp;gt;bufferram = nr_blockdev_pages()&lt;/span&gt;;//block device&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;使用的面框数&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;#ifdef CONFIG_HIGHMEM&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;val-&amp;gt;totalhigh = totalhigh_pages;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;val-&amp;gt;freehigh = nr_free_highpages();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;#else&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;val-&amp;gt;totalhigh = 0;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;val-&amp;gt;freehigh = 0;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;#endif&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;val-&amp;gt;mem_unit = PAGE_SIZE;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;//&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;遍历所有的块设备，累加相应的页面数量&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;long nr_blockdev_pages(void)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;struct list_head *p;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;long ret = 0;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;spin_lock(&amp;amp;bdev_lock);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;list_for_each(p, &amp;amp;all_bdevs) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;struct block_device *bdev;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;bdev = list_entry(p, struct block_device, bd_list);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;ret += bdev-&amp;gt;bd_inode-&amp;gt;i_mapping-&amp;gt;nrpages;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;spin_unlock(&amp;amp;bdev_lock);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;return ret;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;nr_blockdev_pages&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;计算块设备使用的页框数，遍历所有块设备，将使用的页框数相加。而不包含普通文件使用的页框数。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;Cached = get_page_cache_size()-total_swapcache_pages-i.bufferram&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" class="MsoTableGrid" border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes"&gt;&lt;td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt;background: #cccccc; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm; mso-border-alt: solid windowtext .5pt" valign="top" width="568"&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;static inline unsigned long get_page_cache_size(void)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;int ret = atomic_read(&amp;amp;&lt;span style="color: blue"&gt;nr_pagecache&lt;/span&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (unlikely(ret &amp;lt; 0))&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;ret = 0;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;return ret;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;Cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;的大小为内核总的&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;page cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;减去&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;swap cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;和块设备占用的页框数量，实际上&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;即为普通文件的占用的&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;page cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;。实际上，在函数&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;add_to_page_cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;和&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;__add_to_swap_cache &lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;中，都会通过调用&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;pagecache_acct&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;实现对内核变量&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;nr_pagecache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;进行累加。前者对应&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;page cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;，内核读块设备和普通文件使用；后者对应&lt;/span&gt;&lt;span style="font-family: Cambria; mso-hansi-font-family: 'Times New Roman'" lang="EN-US"&gt;swap cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: 'Times New Roman'"&gt;，内核读交换分区使用。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;strong style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-family: Cambria; font-size: 12pt" lang="EN-US"&gt;Page cache(&lt;/span&gt;&lt;/strong&gt;&lt;strong style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-family: 宋体; font-size: 12pt; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;页面缓存&lt;/span&gt;&lt;/strong&gt;&lt;strong style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-family: Cambria; font-size: 12pt" lang="EN-US"&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;在&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;linux&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;系统中，为了加快文件的读写，内核中提供了&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;page cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;作为缓存，称为页面缓存&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;(page cache)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;。为了加快对块设备的读写，内核中还提供了&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;作为缓存。在&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;2.4&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;内核中，这两者是分开的。这样就造成了双缓冲，因为文件读写最后还是转化为对块设备的读写。在&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;2.6&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;中，&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;合并到&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;page cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;中，对应的页面叫作&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer page&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;。当进行文件读写时，如果文件在磁盘上的存储块是连续的，那么文件在&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;page cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;中对应的页是普通的&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;page&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;，如果文件在磁盘上的数据块是不连续的，或者是设备文件，那么文件在&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;page cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;中对应的页是&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer page&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer page&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;与普通的&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;page&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;相比，每个页多了几个&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer_head&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;结构体&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;个数视块的大小而定&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;。此外，如果对单独的块（如超级块）直接进行读写，对应的&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;page cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;中的页也是&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer page&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;。这两种页面虽然形式略有不同，但是最终他们的数据都会被封装成&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;bio&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;结构体，提交到通用块设备驱动层，统一进行&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;I/O&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;调度。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" class="MsoTableGrid" border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes"&gt;&lt;td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt;background: #cccccc; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm; mso-border-alt: solid windowtext .5pt" valign="top" width="568"&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;// include/buffer_head.h &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;struct buffer_head {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* First cache line: */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;unsigned long b_state;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* buffer state bitmap (see above) */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;struct buffer_head *b_this_page;/* circular list of page's buffers */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;struct page *b_page;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* the page this bh is mapped to,&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;页框&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt; */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;atomic_t b_count;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* users using this block */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;u32 b_size;&lt;span style="mso-tab-count: 3"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* block size */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;sector_t b_blocknr;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* block number,&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;块设备中的逻辑块号&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt; */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;char *b_data;&lt;span style="mso-tab-count: 3"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* pointer to data block */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;struct block_device *b_bdev;//&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;块设备&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;bh_end_io_t *b_end_io;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* I/O completion */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;void *b_private;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;/* reserved for b_end_io */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;struct list_head b_assoc_buffers; /* associated with another mapping */&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;};&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;在&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;kernel2.6&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;之后，&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer_head&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;没有别的作用，主要用来保持页框与块设备中数据块的映射关系。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;strong style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-family: Cambria; font-size: 12pt" lang="EN-US"&gt;Buffer page(&lt;/span&gt;&lt;/strong&gt;&lt;strong style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-family: 宋体; font-size: 12pt; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;缓冲页&lt;/span&gt;&lt;/strong&gt;&lt;strong style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-family: Cambria; font-size: 12pt" lang="EN-US"&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;如果内核需要单独访问一个块，就会涉及到&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer page&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;，并会检查对应的&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer head&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;内核创建&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer page&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;的两种常见情况：&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;(1)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;当读或者写一个文件页的数据块不相邻时。发生这种情况是因为文件系统为文件分配了非连续的块，或者文件有洞。具体请参见&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;block_read_full_page(fs/buffer.c)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;函数&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" class="MsoTableGrid" border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes"&gt;&lt;td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt;background: #cccccc; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm; mso-border-alt: solid windowtext .5pt" valign="top" width="568"&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;///&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;对于块设备文件和数据块不相邻的普通文件&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;,&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;都会调用该方法&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;int block_read_full_page(struct page *page, get_block_t *get_block)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&amp;#8230;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (!page_has_buffers(page))///page&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;没有分配&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer head,&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;见&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer_head.h&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;create_empty_buffers(page, blocksize, 0);//&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;为&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;page&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;创建&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer_head&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;head = page_buffers(page);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;这里使用&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer head&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;主要是通过&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer head&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;建立页框与数据块的映射关系。因为页面中的数据不是连接的，而页框描述符&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;struct page&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;的字段又不足以表达这种信息。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;(2)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;访问一个单独的磁盘块&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;(&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;比如，读超级块或者索引节点块时&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;。参见&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;ext2_fill_super(fs/ext2/super.c)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;，该函数在安装&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;ext2&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;文件系统时调用。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;Buffer page&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;和&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer head&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;的关系：&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;div align="center"&gt;&lt;img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/hustcat/2011/cache3.png" width="536" height="361" /&gt;&lt;/div&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal" align="center"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;小结：对于普通文件，如果页面中的块是连续的，则页面没有对应&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer head&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;；如果不连续，则页面有对应的&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer head&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;，参见&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;do_mpage_readpage&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;函数。对于块设备，无论是读取单独的数据块，还是作为设备文件来进行读取，页面始终有对应的&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer head&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;，参见&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;block_read_full_page/__bread&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;函数。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;strong style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-family: Cambria; font-size: 12pt" lang="EN-US"&gt;Swap cache(&lt;/span&gt;&lt;/strong&gt;&lt;strong style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-family: 宋体; font-size: 12pt; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;交换缓存&lt;/span&gt;&lt;/strong&gt;&lt;strong style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-family: Cambria; font-size: 12pt" lang="EN-US"&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;在图&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;1-2&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;中，有一行&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;swapcached&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;，它表示交换缓存的大小。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;Page cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;是磁盘数据在内存中的缓存，而&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;swap cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;则是交换分区在内存中的临时缓存。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;Swap cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;对交换分区具有十分重要的意义，这里不再赘述，详细讨论请见参考文献。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;Swap&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;用来为非映射页在磁盘上提供备份。有三类页必须由交换子系统进行处理：&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;(1)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;进程匿名线性区&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;(anonymous memory region)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;的页，比如用户态的堆栈和堆，匿名内存映射也是。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;(2)&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;进程私有内存映射的脏页。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;(3)IPC&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;共享内存区的页。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;1&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;和&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;3&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;都比较好理解，因为它们都没有对应的磁盘文件，所以必须通过&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;swap&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;来临时存储数据。下面讨论一下第&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;2&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;点。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;strong style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-family: Cambria; font-size: 12pt" lang="EN-US"&gt;Memory mapping(&lt;/span&gt;&lt;/strong&gt;&lt;strong style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-family: 宋体; font-size: 12pt; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;内存映射&lt;/span&gt;&lt;/strong&gt;&lt;strong style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-family: Cambria; font-size: 12pt" lang="EN-US"&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;内核有两种类型的内存映射：共享型&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;(shared)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;和私有型&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;(private)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;。私有型是当进程为了只读文件，而不写文件时使用，这时，私有映射更加高效。但是，任何对私有映射页的写操作都会导致内核停止映射该文件中的页。所以，写操作既不会改变磁盘上的文件，对访问该文件的其它进程也是不可见的。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;共享内存中的页通常都位于&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;page cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;，私有内存映射只要没有修改，也位于&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;page cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;。当进程试图修改一个私有映射内存页时，内核就把该页进行复制，并在页表中用复制的页替换原来的页。由于修改了页表，尽管原来的页仍然在&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;page cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;，但是已经不再属于该内存映射。而新复制的页也不会插入&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;page cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;，而是添加到匿名页反向映射数据结构。参见&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;do_no_page(mm/memory.c)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" class="MsoTableGrid" border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes"&gt;&lt;td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt;background: #cccccc; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm; mso-border-alt: solid windowtext .5pt" valign="top" width="568"&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;static int&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;do_no_page(struct mm_struct *mm, struct vm_area_struct *vma,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;unsigned long address, int write_access, pte_t *page_table, pmd_t *pmd)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&amp;#8230;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/span&gt;//&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;写私有内存映射&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;,&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;则复制页面&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (write_access &amp;amp;&amp;amp; !(vma-&amp;gt;vm_flags &amp;amp; VM_SHARED)) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;struct page *page;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (unlikely(anon_vma_prepare(vma)))&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 3"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;goto oom;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;page = alloc_page_vma(GFP_HIGHUSER, vma, address);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (!page)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 3"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;goto oom;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;copy_user_highpage(page, new_page, address);///copy page&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;page_cache_release(new_page);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;new_page = page;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;anon = 1;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&amp;#8230;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if (anon) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 3"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;lru_cache_add_active(new_page);//&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;将页插入&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;LRU&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;的活动链表&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 3"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;page_add_anon_rmap(new_page, vma, address);//&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;将匿名页插入到反向映射数据结构&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&amp;#8230;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;strong style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-family: 宋体; font-size: 12pt; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;释放&lt;/span&gt;&lt;/strong&gt;&lt;strong style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-family: Cambria; font-size: 12pt" lang="EN-US"&gt;cache&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;Free&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;命令输出的第一行是对应的实实在在的内存，不管是&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;buffer&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;，还是&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;Swap&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;对应磁盘上的交换分区。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;Kernel&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;会尽量使用&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;RAM&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;做&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;，所以一般&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;都比较大：&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;&lt;/span&gt;&lt;strong style="mso-bidi-font-weight: normal"&gt;&lt;span style="font-family: Cambria; font-size: 12pt" lang="EN-US"&gt;&lt;o:p&gt;&lt;img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/hustcat/2011/cache4.png" width="737" height="102" /&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;st1:chmetcnv w:st="on" unitname="g" sourcevalue="8" hasspace="False" negative="False" numbertype="1" tcsc="0"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;8G&lt;/span&gt;&lt;/st1:chmetcnv&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;的内存，而空闲&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;(free)&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;的内存只有约&lt;/span&gt;&lt;st1:chmetcnv w:st="on" unitname="m" sourcevalue="50" hasspace="False" negative="False" numbertype="1" tcsc="0"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;50M&lt;/span&gt;&lt;/st1:chmetcnv&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;，比较惊人。其实，&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;cached&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;占了&lt;/span&gt;&lt;st1:chmetcnv w:st="on" unitname="g" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;3G&lt;/span&gt;&lt;/st1:chmetcnv&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;+&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;。另外，我们看到第三行&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;used&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;列约为&lt;/span&gt;&lt;st1:chmetcnv w:st="on" unitname="g" sourcevalue="4" hasspace="False" negative="False" numbertype="1" tcsc="0"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;4G&lt;/span&gt;&lt;/st1:chmetcnv&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;，是比较大的，确实，该机器上跑了好几个接入服务。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp; &lt;div align="center"&gt;&lt;/div&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;Kernel&lt;st1:chsdate w:st="on" year="1899" month="12" day="30" islunardate="False" isrocdate="False"&gt;2.6.16&lt;/st1:chsdate&gt;&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;之后的版本提供了一种释放&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;的机制，通过修改内核参数&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;/proc/sys/vm/drop_caches&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;让内核释放干净的&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;To free pagecache:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;echo 1 &amp;gt; /proc/sys/vm/drop_caches&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;To free dentries and inodes:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;echo 2 &amp;gt; /proc/sys/vm/drop_caches&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;To free pagecache, dentries and inodes:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;echo 3 &amp;gt; /proc/sys/vm/drop_caches &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" class="MsoTableGrid" border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;&lt;tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes"&gt;&lt;td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 426.1pt; padding-right: 5.4pt;background: #cccccc; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm; mso-border-alt: solid windowtext .5pt" valign="top" width="568"&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;# free&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;total&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;used&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;free&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;shared&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;buffers&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;cached&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;Mem:&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1966220&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1676428&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;289792&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;0&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;418900&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: blue"&gt;705216&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;-/+ buffers/cache:&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;552312&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1413908&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;Swap:&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;2104504&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;131084&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1973420&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;# echo 1 &amp;gt; /proc/sys/vm/drop_caches&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;# free&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/span&gt;total&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;used&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;free&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;shared&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;buffers&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;cached&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;Mem:&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1966220&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;597840&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1368380&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;0&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;324&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: blue"&gt;65852&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;-/+ buffers/cache:&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;531664&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1434556&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;Swap:&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;2104504&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;131084&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1973420&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;设置内核参数&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;drop_caches&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;后，&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;cached&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;的值迅速下降。通常来说，&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;Linux&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;会尽量使用可用的&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;RAM&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;，&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;过高，是正常的。而手动释放&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;cache&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;会增加&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;I/O&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;开销，导致系统性能下降。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;最后，水平有限，欢迎指正和探讨。&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;主要参考：&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;《&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;ULK&lt;/span&gt;&lt;span style="font-family: 宋体; mso-ascii-font-family: Cambria; mso-hansi-font-family: Cambria"&gt;》&lt;/span&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;font face="Times New Roman"&gt;http://linux.die.net/man/1/free&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;http://www.kernel.org/doc/Documentation/sysctl/vm.txt&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;a href="http://linux-mm.org/Drop_Caches"&gt;http://linux-mm.org/Drop_Caches&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family: Cambria" lang="EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;div id="AllanboltSignature"&gt;&lt;p id="PSignature"&gt;&lt;br /&gt;作者：MrDB &lt;br /&gt;出处：&lt;a href="http://www.cnblogs.com/hustcat/" target="_blank"&gt;http://www.cnblogs.com/hustcat/&lt;/a&gt; &lt;br /&gt;本文版权归作者和博客园共有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。 &lt;/p&gt;&lt;/div&gt;&lt;p class="MsoNormal"&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/hustcat/aggbug/2226995.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hustcat/archive/2011/10/27/2226995.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hustcat/archive/2011/03/30/2000401.html</id><title type="text">数据库牛人榜(随时更新)</title><summary type="text">一些不得不记住的数据库大牛</summary><published>2011-03-30T15:21:00Z</published><updated>2011-03-30T15:21:00Z</updated><author><name>MrDB</name><uri>http://www.cnblogs.com/hustcat/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hustcat/archive/2011/03/30/2000401.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hustcat/archive/2011/03/30/2000401.html"/><content type="html">&lt;p&gt;Edgar F. Codd：1981年图灵奖，以他命名的SIGMOD Innovations Award。&lt;a href="http://en.wikipedia.org/wiki/Edgar_F._Codd"&gt;http://en.wikipedia.org/wiki/Edgar_F._Codd&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Jim Gray: 事务处理的权威，1998年图灵奖。&lt;a href="http://en.wikipedia.org/wiki/Jim_Gray_(computer_scientist"&gt;http://en.wikipedia.org/wiki/Jim_Gray_(computer_scientist&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Michael Stonebraker：Professor of Computer Science at University of California, Berkeley，参与开发Ingres和Postgres（这两项足以傲视群雄）。&lt;a href="http://en.wikipedia.org/wiki/Michael_Stonebraker"&gt;http://en.wikipedia.org/wiki/Michael_Stonebraker&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;img src="http://www.cnblogs.com/hustcat/aggbug/2000401.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hustcat/archive/2011/03/30/2000401.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hustcat/archive/2010/09/07/1820970.html</id><title type="text">ACID、Data Replication、CAP与BASE</title><summary type="text">一些分布式计算理论方面的小结</summary><published>2010-09-07T13:40:00Z</published><updated>2010-09-07T13:40:00Z</updated><author><name>MrDB</name><uri>http://www.cnblogs.com/hustcat/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hustcat/archive/2010/09/07/1820970.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hustcat/archive/2010/09/07/1820970.html"/><content type="html">&lt;p&gt;&lt;strong&gt;ACID&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体"&gt;在传数据库系统中，事务具有&lt;/span&gt;ACID 4&lt;span style="font-family: 宋体"&gt;个属性&lt;/span&gt;(Jim Gray&lt;span style="font-family: 宋体"&gt;在《事务处理：概念与技术》中对事务进行了详尽的讨论&lt;/span&gt;)&lt;span style="font-family: 宋体"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;(1)&lt;span style="font-family: 宋体"&gt;原子性（&lt;/span&gt;Atomicity&lt;span style="font-family: 宋体"&gt;）：事务是一个原子操作单元，其对数据的修改，要么全都执行，要么全都不执行。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;(2)&lt;span style="font-family: 宋体"&gt;一致性（&lt;/span&gt;Consistent&lt;span style="font-family: 宋体"&gt;）：在事务开始和完成时，数据都必须保持一致状态。这意味着所有相关的数据规则都必须应用于事务的修改，以保持数据的完整性；事务结束时，所有的内部数据结构（如&lt;/span&gt;B&lt;span style="font-family: 宋体"&gt;树索引或双向链表）也都必须是正确的。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;(3)&lt;span style="font-family: 宋体"&gt;隔离性（&lt;/span&gt;Isolation&lt;span style="font-family: 宋体"&gt;）：数据库系统提供一定的隔离机制，保证事务在不受外部并发操作影响的&amp;#8220;独立&amp;#8221;环境执行。这意味着事务处理过程中的中间状态对外部是不可见的，反之亦然。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;(4)&lt;span style="font-family: 宋体"&gt;持久性（&lt;/span&gt;Durable&lt;span style="font-family: 宋体"&gt;）：事务完成之后，它对于数据的修改是永久性的，即使出现系统故障也能够保持。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体"&gt;对于单个节点的事务，数据库都是通过并发控制（两阶段封锁，&lt;/span&gt;two phase locking&lt;span style="font-family: 宋体"&gt;或者多版本，&lt;/span&gt;multiversioning&lt;span style="font-family: 宋体"&gt;）和恢复机制（日志技术）保证事务的&lt;/span&gt;ACID&lt;span style="font-family: 宋体"&gt;特性。对于跨多个节点的分布式事务，通过两阶段提交协议（&lt;/span&gt;two phase commiting&lt;span style="font-family: 宋体"&gt;）来保证事务的&lt;/span&gt;ACID&lt;span style="font-family: 宋体"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体"&gt;可以说，数据库系统是伴随着金融业的需求而快速发展起来。对于金融业，可用性和性能都不是最重要的，而一致性是最重要的，用户可以容忍系统故障而停止服务，但绝不能容忍帐户上的钱无故减少&lt;/span&gt;(&lt;span style="font-family: 宋体"&gt;当然，无故增加是可以的&lt;/span&gt;)&lt;span style="font-family: 宋体"&gt;。而强一致性的事务是这一切的根本保证。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span&gt;Data Replication&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体"&gt;数据复制&lt;/span&gt;(data replication)&lt;span style="font-family: 宋体"&gt;属于分布式计算的范畴，它并不仅仅局限于数据库，但这里主要是指分布式数据库的复制。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体"&gt;在多副本构成的分布式数据库系统中，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;其事务特性与单个数据库系统的差别主要表现在原子性和一致性两个方&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;面。在原子性方面，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;要求同一分布式事务的所有操作在所有相关副本上要么提交，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;要么回滚，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;即除了保证原有的局部事务的原子性，还需要控制全局事务的原子性；&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;在一致性方面，多副本之间需要保证单一副本一致性。&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体"&gt;针对分布式事务的原子性和一致性这两个复制协议中的核心问题，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;经过近&lt;/span&gt;20&lt;span style="font-family: 宋体"&gt;年的研究&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;人们提出了各种各样的复制协议。这些协议在外在功能和内部实现两方面都有较大的差别。据此，我们可以从这两个大的方面进行分类说明。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体"&gt;从外在功能的角度看，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;依据文献&lt;/span&gt;[1]&lt;span style="font-family: 宋体"&gt;，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;可以从事务执行的地点和时间两个方面进行分类。从事务执行的地点，可以分为两类：&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;主从&lt;/span&gt;( Priamry / Copy)&lt;span style="font-family: 宋体"&gt;方式和更新所有&lt;/span&gt;( Update-Anywhere ) &lt;span style="font-family: 宋体"&gt;方式。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体"&gt;前者的处理过程一般是系统中仅仅指定一个&lt;/span&gt;Primary&lt;span style="font-family: 宋体"&gt;节点接受更新请求&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;在事务操作执行完毕后，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;在事务提交前或后将操作广播到其他&lt;/span&gt;Copy&lt;span style="font-family: 宋体"&gt;节点。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体"&gt;后者的处理过程稍微复杂，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;系统中的任何副本具有相同的地位，都可以接收&lt;/span&gt;Update&lt;span style="font-family: 宋体"&gt;请求&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;，在检测事务冲突、&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;事务提交前或后将各个节点的&lt;/span&gt;Update&lt;span style="font-family: 宋体"&gt;传播到其他副本节点。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Primary / Copy&lt;span style="font-family: 宋体"&gt;方式并发控制较为简单，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;由&lt;/span&gt;Primary&lt;span style="font-family: 宋体"&gt;本地的事务控制即可实现，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;事务的原子性的实现也较为简单，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;一般由&lt;/span&gt;Primary&lt;span style="font-family: 宋体"&gt;节点作为协调节点来实现。但是，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;其缺陷也显而易见：&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;仅仅单个节点提供&lt;/span&gt;Update&lt;span style="font-family: 宋体"&gt;请求处理能力，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;对于&lt;/span&gt;Update&lt;span style="font-family: 宋体"&gt;密集类型的应用，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;如&lt;/span&gt;OLTP&lt;span style="font-family: 宋体"&gt;，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;容易形成单点性能瓶颈。&lt;/span&gt;Update-Anywhere&lt;span style="font-family: 宋体"&gt;方式则与其相辅相成，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;可以通过多点提高事务吞吐率，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;但随之而来的是多个分布式事务之间复杂的并发控制和原子性问题。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: 宋体"&gt;从事务提交的时间点看，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;可以分为积极&lt;/span&gt; (Eager)&lt;span style="font-family: 宋体"&gt;和消极&lt;/span&gt;(Lazy) &lt;span style="font-family: 宋体"&gt;两类。其区别在于，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;前者是在事务提交前传播更新，后者则是在提交之后才将事务操作传播到其他副本。实际上，前者即通常无谓的同步复制&lt;/span&gt;(synchronous replication)&lt;span style="font-family: 宋体"&gt;，后者即无谓的异步复制&lt;/span&gt;(asynchronous replication)&lt;span style="font-family: 宋体"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体"&gt;异步复制的优点是可以提高响应速度，&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;但牺牲了一致性&lt;/span&gt; &lt;span style="font-family: 宋体"&gt;，一般实现该类协议的算法需要增加额外的补偿机制。同步复制的优点是可以保证一致性&lt;/span&gt;(&lt;span style="font-family: 宋体"&gt;一般通过两阶段提交协议&lt;/span&gt;)&lt;span style="font-family: 宋体"&gt;，但是开销较大，可用性不好&lt;/span&gt;(&lt;span style="font-family: 宋体"&gt;参见&lt;/span&gt;CAP&lt;span style="font-family: 宋体"&gt;部分&lt;/span&gt;)&lt;span style="font-family: 宋体"&gt;，带来了更多的冲突和死锁等问题。值得一提的是&lt;/span&gt;Lazy+Primary/Copy&lt;span style="font-family: 宋体"&gt;的复制协议在实际生产环境中是非常实用的，&lt;/span&gt;MySQL&lt;span style="font-family: 宋体"&gt;的复制实际上就属于这种。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;CAP&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体"&gt;在&lt;/span&gt;2000&lt;span style="font-family: 宋体"&gt;的&lt;/span&gt;PODC&lt;span style="font-family: 宋体"&gt;（&lt;/span&gt;Principles of Distributed Computing&lt;span style="font-family: 宋体"&gt;）会议上，&lt;/span&gt;Brewer&lt;span style="font-family: 宋体"&gt;提出了著名的&lt;/span&gt;CAP&lt;span style="font-family: 宋体"&gt;理论。&lt;/span&gt;2002&lt;span style="font-family: 宋体"&gt;年，&lt;/span&gt;Seth Gilbert&lt;span style="font-family: 宋体"&gt;和&lt;/span&gt;Nancy Lynch&lt;span style="font-family: 宋体"&gt;证明了这一理论。&lt;/span&gt;CAP&lt;span style="font-family: 宋体"&gt;指的是：&lt;/span&gt;Consistency&lt;span style="font-family: 宋体"&gt;、&lt;/span&gt;Availability&lt;span style="font-family: 宋体"&gt;和&lt;/span&gt;Partition&amp;nbsp;Tolerance&lt;span style="font-family: 宋体"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体"&gt;（&lt;/span&gt;1&lt;span style="font-family: 宋体"&gt;）&lt;/span&gt;Consistency&lt;span style="font-family: 宋体"&gt;（一致性）：一致性是说数据的原子性，这种原子性在经典的数据库中是通过事务来保证的，当事务完成时，无论其是成功还是回滚，数据都会处于一致的状态。在分布式环境中，一致性是说多个节点的数据是否一致。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体"&gt;（&lt;/span&gt;2&lt;span style="font-family: 宋体"&gt;）&lt;/span&gt;Availability&lt;span style="font-family: 宋体"&gt;（可用性）：可用性是说服务能一直保证是可用的状态，当用户发出一个请求，服务能在有限时间内返回结果。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体"&gt;（&lt;/span&gt;3&lt;span style="font-family: 宋体"&gt;）&lt;/span&gt;Partition&amp;nbsp;Tolerance&lt;span style="font-family: 宋体"&gt;（分区容错性）：&lt;/span&gt;Partition&lt;span style="font-family: 宋体"&gt;是指网络的分区。可以这样理解，一般来说，关键的数据和服务都会位于不同的&lt;/span&gt;IDC&lt;span style="font-family: 宋体"&gt;。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: black"&gt;CAP&lt;/span&gt;&lt;span style="font-family: 宋体; color: black"&gt;理论告诉我们，一个分布式系统不可能同时满足一致性，可用性和分区容错性这三个需求，三个要素中最多只能同时满足两点。三者不可兼顾，此所谓鱼与熊掌不可兼得也！而对于分布式数据系统而言，分区容错性是基本要求，否则就不称其为分布式系统了。因此架构设计师不要把精力浪费在设计如何能同时满足三者的完美分布式系统上，而是应该进行权衡取舍。这也意味着分布式系统的设计过程，也就是根据业务特点在&lt;/span&gt;&lt;span style="color: black"&gt;C&lt;/span&gt;&lt;span style="font-family: 宋体; color: black"&gt;（一致性）和&lt;/span&gt;&lt;span style="color: black"&gt;A&lt;/span&gt;&lt;span style="font-family: 宋体; color: black"&gt;（可用性）之间寻求平衡的过程，要求架构师真正理解系统需求，把握业务特点。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;BASE&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;BASE&lt;span style="font-family: 宋体"&gt;来自于互联网的电子商务领域的实践，它是基于&lt;/span&gt;CAP&lt;span style="font-family: 宋体"&gt;理论逐步演化而来，核心思想是即便不能达到强一致性&lt;/span&gt;&lt;span&gt;(Strong consistency)&lt;/span&gt;&lt;span style="font-family: 宋体"&gt;，但可以根据应用特点采用适当的方式来达到最终一致性&lt;/span&gt;(Eventual consistency)&lt;span style="font-family: 宋体"&gt;的效果。&lt;/span&gt;BASE&lt;span style="font-family: 宋体"&gt;是&lt;/span&gt;&lt;span&gt;Basically Available&lt;/span&gt;&lt;span style="font-family: 宋体"&gt;、&lt;/span&gt;Soft state&lt;span style="font-family: 宋体"&gt;、&lt;/span&gt;Eventually consistent&lt;span style="font-family: 宋体"&gt;三个词组的简写，是对&lt;/span&gt;CAP&lt;span style="font-family: 宋体"&gt;中&lt;/span&gt;C &amp;amp; A&lt;span style="font-family: 宋体"&gt;的延伸。&lt;/span&gt;BASE&lt;span style="font-family: 宋体"&gt;的含义：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体"&gt;（&lt;/span&gt;1&lt;span style="font-family: 宋体"&gt;）&lt;/span&gt;&lt;span&gt;Basically Available&lt;/span&gt;&lt;span style="font-family: 宋体"&gt;：基本可用；&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体"&gt;（&lt;/span&gt;2&lt;span style="font-family: 宋体"&gt;）&lt;/span&gt;Soft-state&lt;span style="font-family: 宋体"&gt;：软状态&lt;/span&gt;/&lt;span style="font-family: 宋体"&gt;柔性事务，即状态可以有一段时间的不同步；&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体"&gt;（&lt;/span&gt;3&lt;span style="font-family: 宋体"&gt;）&lt;/span&gt;&lt;span&gt;Eventual consistency&lt;/span&gt;&lt;span style="font-family: 宋体"&gt;：最终一致性；&lt;/span&gt;&lt;/p&gt;&lt;p&gt;BASE&lt;span style="font-family: 宋体"&gt;是反&lt;/span&gt;ACID&lt;span style="font-family: 宋体"&gt;的，它完全不同于&lt;/span&gt;ACID&lt;span style="font-family: 宋体"&gt;模型，牺牲强一致性，获得基本可用性和柔性可靠性并要求达到最终一致性。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;CAP&lt;span style="font-family: 宋体"&gt;、&lt;/span&gt;BASE&lt;span style="font-family: 宋体"&gt;理论是当前在互联网领域非常流行的&lt;/span&gt;NoSQL&lt;span style="font-family: 宋体"&gt;的理论基础。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 宋体"&gt;主要参考&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 9pt"&gt;[1]J.N.Gray, P.Helland,and a.D.S.P.O&amp;#8217;Neil. The dangers of replication and a solution. In Proceedings of the 1996 ACM SIGMOD International Conference on Management of Data, pages 173&amp;#8211;182,Montreal, Canada, June 1996.SIGMOD.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;[2]Gilbert , S., Lynch, N. 2002. Brewer&amp;#8217;s conjecture and the feasibility of consistent, available, partition-tolerant Web services. ACM SIGACT News 33(2).&lt;/span&gt;&lt;/p&gt;&lt;p&gt;[3]&lt;a href="http://www.allthingsdistributed.com/2008/12/eventually_consistent.html"&gt;http://www.allthingsdistributed.com/2008/12/eventually_consistent.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;[4]http://queue.acm.org/detail.cfm?id=1394128&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: 'Times New Roman'; font-size: 10.5pt"&gt;[5]&lt;a href="http://en.wikipedia.org/wiki/ACID"&gt;http://en.wikipedia.org/wiki/ACID&lt;/a&gt;&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div id="AllanboltSignature"&gt;&lt;p id="PSignature"&gt;&lt;br /&gt;作者：&lt;a href="http://www.cnblogs.com/hustcat/" target="_blank"&gt;arrowcat&lt;/a&gt; &lt;br /&gt;出处：&lt;a href="http://www.cnblogs.com/hustcat/" target="_blank"&gt;http://www.cnblogs.com/hustcat/&lt;/a&gt; &lt;br /&gt;本文版权归作者和博客园共有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。 &lt;/p&gt;&lt;/div&gt; &lt;img src="http://www.cnblogs.com/hustcat/aggbug/1820970.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hustcat/archive/2010/09/07/1820970.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hustcat/archive/2010/08/31/1814022.html</id><title type="text">libevent源码分析</title><summary type="text">这两天没事，看了一下Memcached和libevent的源码，做个小总结。</summary><published>2010-08-31T12:49:00Z</published><updated>2010-08-31T12:49:00Z</updated><author><name>MrDB</name><uri>http://www.cnblogs.com/hustcat/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hustcat/archive/2010/08/31/1814022.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hustcat/archive/2010/08/31/1814022.html"/><content type="html">&lt;p&gt; &lt;/p&gt;&lt;p&gt;&amp;nbsp;这两天没事，看了一下Memcached和libevent的源码，做个小总结。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;1、入门&lt;/p&gt;1.1、概述&lt;br /&gt;Libevent是一个用于开发可扩展性网络服务器的基于事件驱动(event-driven)模型的网络库。Libevent有几个显著的亮点： &lt;br /&gt;(1)事件驱动（event-driven），高性能；&lt;br /&gt;(2)轻量级，专注于网络，不如 ACE 那么臃肿庞大； &lt;br /&gt;(3)源代码相当精炼、易读； &lt;br /&gt;(4)跨平台，支持 Windows、Linux、*BSD和 Mac Os； &lt;br /&gt;(5)支持多种 I/O多路复用技术， epoll、poll、dev/poll、select 和kqueue 等； &lt;br /&gt;(6)支持 I/O，定时器和信号等事件； &lt;br /&gt;(7)注册事件优先级； &lt;br /&gt;&amp;nbsp;Libevent 已经被广泛的应用，作为底层的网络库；比如 memcached、 Vomi t、 Nylon、 Netchat等等。&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;1.2、一个简单示例&lt;br /&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('a0d707ef-fc9d-451c-8de3-aff98717b9de')"&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" class="code_img_closed" id="code_img_closed_a0d707ef-fc9d-451c-8de3-aff98717b9de" alt="" /&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" class="code_img_opened" id="code_img_opened_a0d707ef-fc9d-451c-8de3-aff98717b9de" onclick="cnblogs_code_hide('a0d707ef-fc9d-451c-8de3-aff98717b9de',event)" style="display: none;"&gt;&lt;div id="cnblogs_code_open_a0d707ef-fc9d-451c-8de3-aff98717b9de" class="cnblogs_code_hide"&gt;&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;lasttime;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;timeout_cb(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;fd,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;short&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;event&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;arg)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;timeval&amp;nbsp;tv;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;event&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;timeout&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;arg;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;newtime&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;time(NULL);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;printf("%s:&amp;nbsp;called&amp;nbsp;at&amp;nbsp;%d:&amp;nbsp;%d\n",&amp;nbsp;__func__,&amp;nbsp;newtime,&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;printf(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;%s:&amp;nbsp;called&amp;nbsp;at&amp;nbsp;%d:&amp;nbsp;%d\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;timeout_cb&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;newtime,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;newtime&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;lasttime);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;lasttime&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;newtime;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;evutil_timerclear(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;tv);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;tv.tv_sec&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;重新注册event&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;event_add(timeout,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;tv);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;main&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;argc,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;char&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;**&lt;/span&gt;&lt;span style="color: #000000;"&gt;argv)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;event&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;timeout;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;timeval&amp;nbsp;tv;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;Initalize&amp;nbsp;the&amp;nbsp;event&amp;nbsp;library&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;初始化event环境&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;event_init();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;Initalize&amp;nbsp;one&amp;nbsp;event&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;设置事件&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;evtimer_set(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;timeout,&amp;nbsp;timeout_cb,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;timeout);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;evutil_timerclear(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;tv);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;tv.tv_sec&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;注册事件&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;event_add(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;timeout,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;tv);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;lasttime&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;time(NULL);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;41&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;42&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;等待,分发,处理事件&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;43&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;event_dispatch();&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;44&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;45&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;46&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;这是一个简单的基于libevent的定时器程序，运行结果：&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/hustcat/2010/libevent01.JPG" height="168" width="366" /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;用libevent编程非常简单，只需要调用event_init初始化环境，然后调用event_add注册相应的事件，接着调用event_dispatch等待并处理相应的事件即可。&lt;br /&gt;调用event_add注册事件时，设置其回调函数。Libevent检测到事件发生时，便会调用事件对应的回调用函数，执行相关的业务逻辑。&lt;br /&gt;&lt;br /&gt;1.3、源代码结构&lt;br /&gt;Libevent 的源代码虽然都在一层文件夹下面，但是其代码分类还是相当清晰的，主要可分为头文件、内部使用的头文件、辅助功能函数、日志、libevent 框架、对系统 I/O 多路复用机制的封装、信号管理、定时事件管理、缓冲区管理、基本数据结构和基于 libevent的两个实用库等几个部分，有些部分可能就是一个源文件。 &lt;br /&gt;（1）头文件 &lt;br /&gt;主要就是 event.h：事件宏定义、接口函数声明，主要结构体 event 的声明； &lt;br /&gt;（2）内部头文件 &lt;br /&gt;xxx-internal.h：内部数据结构和函数，对外不可见，以达到信息隐藏的目的； &lt;br /&gt;（3）libevent框架 &lt;br /&gt;event.c：event 整体框架的代码实现； &lt;br /&gt;（4）对系统 I/O多路复用机制的封装 &lt;br /&gt;epoll.c：对 epoll 的封装； &lt;br /&gt;select.c：对 select 的封装； &lt;br /&gt;devpoll.c：对 dev/poll 的封装; &lt;br /&gt;kqueue.c：对kqueue 的封装； &lt;br /&gt;（5）定时事件管理 &lt;br /&gt;min-heap.h：其实就是一个以时间作为 key的小根堆结构； &lt;br /&gt;（6）信号管理 &lt;br /&gt;signal.c：对信号事件的处理； &lt;br /&gt;（7）辅助功能函数 &lt;br /&gt;evutil.h&amp;nbsp; 和 evutil.c：一些辅助功能函数，包括创建 socket pair和一些时间操作函数：加、减和比较等。 &lt;br /&gt;（8）日志 &lt;br /&gt;log.h和 log.c：log 日志函数 &lt;br /&gt;（9）缓冲区管理 &lt;br /&gt;evbuffer.c 和buffer.c：libevent 对缓冲区的封装； &lt;br /&gt;（10）基本数据结构 &lt;br /&gt;compat\sys 下的两个源文件： queue.h是 libevent 基本数据结构的实现，包括链表，双向链表，队列等；_libevent_time.h：一些用于时间操作的结构体定义、函数和宏定义； &lt;br /&gt;（11）实用网络库 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;http 和evdns：是基于 libevent 实现的http 服务器和异步 dns 查询库；&lt;br /&gt;&lt;br /&gt;2、核心对象&lt;br /&gt;结构体event和event_base是libevent的两个核心数据结构，前者代表一个事件对象，后者代表整个事件处理框架。 &lt;br /&gt;2.1、event（事件）&lt;br /&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('4d86404c-1d21-4a28-8be9-6299c6e7c7da')"&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" class="code_img_closed" id="code_img_closed_4d86404c-1d21-4a28-8be9-6299c6e7c7da" style="display: none;" alt="" /&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" class="code_img_opened" id="code_img_opened_4d86404c-1d21-4a28-8be9-6299c6e7c7da" onclick="cnblogs_code_hide('4d86404c-1d21-4a28-8be9-6299c6e7c7da',event)"&gt;&lt;div id="cnblogs_code_open_4d86404c-1d21-4a28-8be9-6299c6e7c7da"&gt;&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;event.h&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;event&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;TAILQ_ENTRY&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;event&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&amp;nbsp;ev_next;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;已注册事件链表&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;TAILQ_ENTRY&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;event&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&amp;nbsp;ev_active_next;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;就绪事件链表&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;TAILQ_ENTRY&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;event&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&amp;nbsp;ev_signal_next;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;signal链表&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;unsigned&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;min_heap_idx;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;for&amp;nbsp;managing&amp;nbsp;timeouts,事件在堆中的下标&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;event_base&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev_base;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;ev_fd;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;对于I/O事件,是绑定的文件描述符;对于signal事件,是绑定的信号&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;short&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;ev_events;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;event关注的事件类型&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;short&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;ev_ncalls;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;事件就绪执行时，调用&amp;nbsp;ev_callback&amp;nbsp;的次数&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;short&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev_pncalls;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;Allows&amp;nbsp;deletes&amp;nbsp;in&amp;nbsp;callback&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;timeval&amp;nbsp;ev_timeout;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;timout事件的超时值&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;ev_pri;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;smaller&amp;nbsp;numbers&amp;nbsp;are&amp;nbsp;higher&amp;nbsp;priority,优先级&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev_callback)(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;short&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;arg);&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;回调函数&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev_arg;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;回调函数的参数&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;ev_res;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;result&amp;nbsp;passed&amp;nbsp;to&amp;nbsp;event&amp;nbsp;callback&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;ev_flags;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;event的状态&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;};&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Libevent通过event对象将I/O事件、信号事件和定时器事件封装，从而统一处理，这也是libevent的精妙所有。&lt;br /&gt;各个字段的具体含义：&lt;br /&gt;(1) ev_events：event关注的事件类型，它可以是以下3种类型： &lt;br /&gt;I/O事件： EV_WRITE和EV_READ &lt;br /&gt;定时事件：EV_TIMEOUT &lt;br /&gt;信号：&amp;nbsp;&amp;nbsp;&amp;nbsp; EV_SIGNAL &lt;br /&gt;辅助选项：EV_PERSIST，表明是一个永久事件 &lt;br /&gt;libevent中的定义为：&lt;br /&gt;#define EV_TIMEOUT&amp;nbsp;&amp;nbsp; &amp;nbsp;0x01&lt;br /&gt;#define EV_READ&amp;nbsp;&amp;nbsp; &amp;nbsp;0x02&lt;br /&gt;#define EV_WRITE&amp;nbsp;&amp;nbsp; &amp;nbsp;0x04&lt;br /&gt;#define EV_SIGNAL&amp;nbsp;&amp;nbsp; &amp;nbsp;0x08&lt;br /&gt;#define EV_PERSIST&amp;nbsp;&amp;nbsp; &amp;nbsp;0x10&amp;nbsp;&amp;nbsp; &amp;nbsp;/* Persistant event */&lt;br /&gt;（2）ev_next，ev_active_next 和 ev_signal_next 都是双向链表节点指针；它们是 libevent 对不同事件类型和在不同的时期，对事件的管理时使用到的字段。 &lt;br /&gt;libevent 使用双向链表保存所有注册的 I/O和 Signal 事件，ev_next 就是该I/O事件在链表中的位置；此链表可以称为&amp;#8220;已注册事件链表&amp;#8221;； &lt;br /&gt;同样 ev_signal_next 就是 signal 事件在 signal 事件链表中的位置； &lt;br /&gt;ev_active_next：libevent 将所有的激活事件放入到链表 active list 中，然后遍历 active list 执&lt;br /&gt;行调度，ev_active_next就指明了 event 在active list 中的位置；&lt;br /&gt;（3）min_heap_idx 和 ev_timeout，如果是 timeout 事件，它们是 event 在小根堆中的索引和超时值，libevent 使用小根堆来管理定时事件。&lt;br /&gt;（4）ev_base指向事件框架实例。&lt;br /&gt;（5）ev_fd，对于 I/O事件，是绑定的文件描述符；对于 signal 事件，是事件对应的信号；&lt;br /&gt;（6）eb_flags：libevent 用于标记 event信息的字段，表明事件当前的状态，可能的值有：&lt;br /&gt;#define EVLIST_TIMEOUT&amp;nbsp;&amp;nbsp; 0x01 // event在time堆中 &lt;br /&gt;#define EVLIST_INSERTED 0x02 // event在已注册事件链表中 &lt;br /&gt;#define EVLIST_SIGNAL&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x04 // 未见使用 &lt;br /&gt;#define EVLIST_ACTIVE&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x08 // event在激活链表中 &lt;br /&gt;#define EVLIST_INTERNAL 0x10 // 内部使用标记 &lt;br /&gt;#define EVLIST_INIT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x80 // event 已被初始化&lt;br /&gt;&lt;br /&gt;2.2、event_base(事件处理框架)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('961ce3af-817a-4860-8152-0d2fc2f41395')"&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" class="code_img_closed" id="code_img_closed_961ce3af-817a-4860-8152-0d2fc2f41395" style="display: none;" alt="" /&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" class="code_img_opened" id="code_img_opened_961ce3af-817a-4860-8152-0d2fc2f41395" onclick="cnblogs_code_hide('961ce3af-817a-4860-8152-0d2fc2f41395',event)"&gt;&lt;div id="cnblogs_code_open_961ce3af-817a-4860-8152-0d2fc2f41395"&gt;&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;evenet_internal.h&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;event_base&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;eventop&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;evsel;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;底层具体I/O&amp;nbsp;demultiplex操作函数集&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;evbase;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;event_count;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;counts&amp;nbsp;number&amp;nbsp;of&amp;nbsp;total&amp;nbsp;events,总的事件数量&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;event_count_active;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;counts&amp;nbsp;number&amp;nbsp;of&amp;nbsp;active&amp;nbsp;events,就绪事件数量&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;event_gotterm;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;Set&amp;nbsp;to&amp;nbsp;terminate&amp;nbsp;loop&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;event_break;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;Set&amp;nbsp;to&amp;nbsp;terminate&amp;nbsp;loop&amp;nbsp;immediately&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;active&amp;nbsp;event&amp;nbsp;management&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;就绪事件链表数组&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;event_list&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;**&lt;/span&gt;&lt;span style="color: #000000;"&gt;activequeues;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;nactivequeues;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;就绪事件队列个数&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;signal&amp;nbsp;handling&amp;nbsp;info&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;evsignal_info&amp;nbsp;sig;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;用于管理信号&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;event_list&amp;nbsp;eventqueue;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;注册事件队列&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;timeval&amp;nbsp;event_tv;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;min_heap&amp;nbsp;timeheap;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;管理定时器的小根堆&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;timeval&amp;nbsp;tv_cache;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;记录时间缓存&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;};&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;（1）evsel：libevent支持Linux、Windows等多种平台，也支持epoll、poll、select、kqueue等多种I/O多路复用模型。如果把event_init、event_add看成高层抽象的统一事件操作接口，则evsel为这些函数在底层具体的I/O demultiplex的对应的操作函数集。eventop为函数指针的集合：&lt;br /&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('e1576c38-2056-4f7a-a47f-52510ef1c22b')"&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" class="code_img_closed" id="code_img_closed_e1576c38-2056-4f7a-a47f-52510ef1c22b" style="display: none;" alt="" /&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" class="code_img_opened" id="code_img_opened_e1576c38-2056-4f7a-a47f-52510ef1c22b" onclick="cnblogs_code_hide('e1576c38-2056-4f7a-a47f-52510ef1c22b',event)"&gt;&lt;div id="cnblogs_code_open_e1576c38-2056-4f7a-a47f-52510ef1c22b"&gt;&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;eventop&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;char&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;name;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;init)(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;event_base&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;add)(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;event&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;del)(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;event&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;dispatch)(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;event_base&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;timeval&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;dealloc)(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;event_base&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;set&amp;nbsp;if&amp;nbsp;we&amp;nbsp;need&amp;nbsp;to&amp;nbsp;reinitialize&amp;nbsp;the&amp;nbsp;event&amp;nbsp;base&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;need_reinit;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;};&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;在初始化函数event_base_new中，libevent将evsel指向全局数组eventops的具体元素：&lt;br /&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('258505a7-b1ac-4e9a-a6c6-0b05ca2cf257')"&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" class="code_img_closed" id="code_img_closed_258505a7-b1ac-4e9a-a6c6-0b05ca2cf257" alt="" /&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" class="code_img_opened" id="code_img_opened_258505a7-b1ac-4e9a-a6c6-0b05ca2cf257" onclick="cnblogs_code_hide('258505a7-b1ac-4e9a-a6c6-0b05ca2cf257',event)" style="display: none;"&gt;&lt;div id="cnblogs_code_open_258505a7-b1ac-4e9a-a6c6-0b05ca2cf257" class="cnblogs_code_hide"&gt;&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;I/O&amp;nbsp;multiplex机制实例数组&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;eventop&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;eventops[]&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;#ifdef&amp;nbsp;HAVE_EVENT_PORTS&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;evportops,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;#endif&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;#ifdef&amp;nbsp;HAVE_WORKING_KQUEUE&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;kqops,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;#endif&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;#ifdef&amp;nbsp;HAVE_EPOLL&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;epollops,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;#endif&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;#ifdef&amp;nbsp;HAVE_DEVPOLL&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;devpollops,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;#endif&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;#ifdef&amp;nbsp;HAVE_POLL&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;pollops,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;#endif&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;#ifdef&amp;nbsp;HAVE_SELECT&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;selectops,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;#endif&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;#ifdef&amp;nbsp;WIN32&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;win32ops,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;#endif&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;NULL&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;};&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;2.3、主要函数&lt;br /&gt;2.3.1、event_int（初始化libevent实例）&lt;br /&gt;struct event_base *&lt;br /&gt;event_init(void)&lt;br /&gt;初始化事件处理框架实例，内部调用event_base_new。&lt;br /&gt;&lt;br /&gt;event_base_new的主要逻辑：&lt;br /&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('c49865cc-6895-4c98-8b19-453f11d0f642')"&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" class="code_img_closed" id="code_img_closed_c49865cc-6895-4c98-8b19-453f11d0f642" style="display: none;" alt="" /&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" class="code_img_opened" id="code_img_opened_c49865cc-6895-4c98-8b19-453f11d0f642" onclick="cnblogs_code_hide('c49865cc-6895-4c98-8b19-453f11d0f642',event)"&gt;&lt;div id="cnblogs_code_open_c49865cc-6895-4c98-8b19-453f11d0f642"&gt;&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;event_base&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;event_base_new(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;初始化小根堆&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;min_heap_ctor(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;timeheap);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;初始化注册事件队列&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;TAILQ_INIT(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;eventqueue);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&amp;nbsp;eventops[i]&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;evbase;&amp;nbsp;i&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;I/O&amp;nbsp;demultiplex机制实例&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;evsel&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;eventops[i];&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;初始化I/O&amp;nbsp;demultiplex实例(参见win32_init)&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;evbase&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;evsel&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;init(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;分配1个就绪事件队列&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;event_base_priority_init(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;2.3.2、event_add（注册事件）&lt;br /&gt;//注册事件&lt;br /&gt;int&lt;br /&gt;event_add(struct event *ev, const struct timeval *tv)&lt;br /&gt;该函数主要将事件ev加入到事件框架event_base的注册事件链表base-&amp;gt;eventqueue。&lt;br /&gt;&lt;br /&gt;2.3.3、event_del（删除事件）&lt;br /&gt;//删除事件&lt;br /&gt;int&lt;br /&gt;event_del(struct event *ev)&lt;br /&gt;该函数主要将事件ev从相应的链表上删除。&lt;br /&gt;&lt;br /&gt;2.3.4、event_set（设置事件）&lt;br /&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('66622623-16cf-4c32-8a75-138bc035cd87')"&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" class="code_img_closed" id="code_img_closed_66622623-16cf-4c32-8a75-138bc035cd87" style="display: none;" alt="" /&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" class="code_img_opened" id="code_img_opened_66622623-16cf-4c32-8a75-138bc035cd87" onclick="cnblogs_code_hide('66622623-16cf-4c32-8a75-138bc035cd87',event)"&gt;&lt;div id="cnblogs_code_open_66622623-16cf-4c32-8a75-138bc035cd87"&gt;&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;设置event对象&lt;br /&gt;**ev:事件对象&lt;br /&gt;**fd:事件对应的文件描述符或信号,对于定时器设为-1&lt;br /&gt;**events:事件类型，比如&amp;nbsp;EV_READ,EV_PERSIST,&amp;nbsp;EV_WRITE,&amp;nbsp;EV_SIGNAL&lt;br /&gt;**callback:事件的回调函数&lt;br /&gt;**arg:回调函数参数&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;event_set(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;event&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;fd,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;short&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;events,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;callback)(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;short&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;),&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;arg)&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;在将事件注册事件处理框架之前，应该先调用event_set对事件进行相关设置。&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;2.4、libevent对event的管理&lt;br /&gt;event结构有3个链表结点域和一个小根堆索引，libevent通过3个链表和一个小根堆对I/O事件、signal事件和timer事件进行管理。&lt;br /&gt;对于I/O事件，通过event_add将其加入event_base的注册事件链表eventqueue ；就绪时会加入event_base的就绪链表activequeues[]；&lt;br /&gt;对于timer事件，event_add将其加入到event_base的小根堆timeheap；&lt;br /&gt;Signale事件的管理相对复杂些，event_add将其加入到注册事件链表，同时，event_add内部会调用I/O demultiplex的add函数（对于I/O事件也一样），比如epoll_add。而add函数又会调用evsignal_add将其加入到evsignal_info的evsigevents[signo]链表(关于signal，后面会详细介绍)。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;3、事件处理框架主循环&lt;br /&gt;Libevent将I/O事件、signal事件和timer事件用统一的模型进行处理，这是非常精妙的。libevent主循环函数不断检测注册事件，如果有事件发生，则将其放入就绪链表，并调用事件的回调函数，完成业务逻辑处理。&lt;br /&gt;3.1、event_dispatch&lt;br /&gt;//事件处理主循环&lt;br /&gt;int&lt;br /&gt;event_dispatch(void)&lt;br /&gt;这是呈现给外部的接口，它的实现很简单，即调用event_loop，而event_loop调用event_base_loop，event_base_loop完成实际的主循环逻辑。&lt;br /&gt;&lt;br /&gt;3.2、event_base_loop&lt;br /&gt;主要算法： &lt;br /&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('5d90d43e-4725-4d0f-829d-f63037f28608')"&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" class="code_img_closed" id="code_img_closed_5d90d43e-4725-4d0f-829d-f63037f28608" alt="" /&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" class="code_img_opened" id="code_img_opened_5d90d43e-4725-4d0f-829d-f63037f28608" onclick="cnblogs_code_hide('5d90d43e-4725-4d0f-829d-f63037f28608',event)" style="display: none;"&gt;&lt;div id="cnblogs_code_open_5d90d43e-4725-4d0f-829d-f63037f28608" class="cnblogs_code_hide"&gt;&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;done&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;done)&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;如果没有就绪事件,根据timer&amp;nbsp;heap中事件的最小超时时间,计算I/O&amp;nbsp;demultiplex的&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;**最大等待时间.&amp;nbsp;相反,如果有就绪事件,则清除tv,即I/O&amp;nbsp;demultiplex不应该等待.&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;event_count_active&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;(flags&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;EVLOOP_NONBLOCK))&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;timeout_next(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;tv_p);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;}&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*&amp;nbsp;if&amp;nbsp;we&amp;nbsp;have&amp;nbsp;active&amp;nbsp;events,&amp;nbsp;we&amp;nbsp;just&amp;nbsp;poll&amp;nbsp;new&amp;nbsp;events&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*&amp;nbsp;without&amp;nbsp;waiting.&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;evutil_timerclear(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;tv);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;If&amp;nbsp;we&amp;nbsp;have&amp;nbsp;no&amp;nbsp;events,&amp;nbsp;we&amp;nbsp;just&amp;nbsp;exit&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;没有事件处理,则退出循环&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;event_haveevents(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;))&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;event_debug((&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;%s:&amp;nbsp;no&amp;nbsp;events&amp;nbsp;registered.&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;__func__));&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;tv_p为I/O&amp;nbsp;demultiplex的超时时间&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;处理signal事件和I/O事件&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;res&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;evsel&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;dispatch(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;evbase,&amp;nbsp;tv_p);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;处理timeout事件,对于超时的事件,将其放到就绪事件链表&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;timeout_process(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;event_count_active)&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;处理就绪事件&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;event_process_active(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;event_count_active&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(flags&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;EVLOOP_ONCE))&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;done&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;}&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(flags&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;EVLOOP_NONBLOCK)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;done&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;end&amp;nbsp;while&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;3.3、timeout_next&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('422d4a90-9a5b-47e5-893c-acb5bda7f115')"&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" class="code_img_closed" id="code_img_closed_422d4a90-9a5b-47e5-893c-acb5bda7f115" alt="" /&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" class="code_img_opened" id="code_img_opened_422d4a90-9a5b-47e5-893c-acb5bda7f115" onclick="cnblogs_code_hide('422d4a90-9a5b-47e5-893c-acb5bda7f115',event)" style="display: none;"&gt;&lt;div id="cnblogs_code_open_422d4a90-9a5b-47e5-893c-acb5bda7f115" class="cnblogs_code_hide"&gt;&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;根据timer&amp;nbsp;heap中事件的最小超时时间,计算I/O&amp;nbsp;demultiplex的最大等待时间.&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;**为了及时处理timer事件,I/O&amp;nbsp;demultiplex的最大等待时间不应该超过timer事件中最小的超时时间,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;**否则,timer事件就不能得到及时处理&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;timeout_next(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;event_base&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;timeval&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;**&lt;/span&gt;&lt;span style="color: #000000;"&gt;tv_p)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;timeval&amp;nbsp;now;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;event&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;timeval&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;tv&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;tv_p;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;如果没有timer事件,则直接返回&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;((ev&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;min_heap_top(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;timeheap))&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;NULL)&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;if&amp;nbsp;no&amp;nbsp;time-based&amp;nbsp;events&amp;nbsp;are&amp;nbsp;active&amp;nbsp;wait&amp;nbsp;for&amp;nbsp;I/O&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;tv_p&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;NULL;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(gettime(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;now)&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;如果最小的timer事件已经超时,则清除tv,即I/O&amp;nbsp;demultiplex不应该等待.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(evutil_timercmp(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev_timeout,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;now,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;))&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;evutil_timerclear(tv);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;更新I/O&amp;nbsp;demultiplex可以等待的最大时间:ev-&amp;gt;ev_timeout&amp;nbsp;-&amp;nbsp;now&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;evutil_timersub(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev_timeout,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;now,&amp;nbsp;tv);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;3.4、dispatch函数&lt;br /&gt;调用底层I/O multiplex的dispatch函数，具体的实现可以参见epoll的实现epoll_dispatch。&lt;br /&gt;&lt;br /&gt;3.5、event_process_active&lt;br /&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('4b11f944-e693-44b2-bc52-94d1a1860bb0')"&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" class="code_img_closed" id="code_img_closed_4b11f944-e693-44b2-bc52-94d1a1860bb0" alt="" /&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" class="code_img_opened" id="code_img_opened_4b11f944-e693-44b2-bc52-94d1a1860bb0" onclick="cnblogs_code_hide('4b11f944-e693-44b2-bc52-94d1a1860bb0',event)" style="display: none;"&gt;&lt;div id="cnblogs_code_open_4b11f944-e693-44b2-bc52-94d1a1860bb0" class="cnblogs_code_hide"&gt;&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;处理就绪事件.&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;**就绪事件位于优先级队列中,低优先级通常比高优先级队列先处理,所以,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;**高优先级队列可能饿死.&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;event_process_active(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;event_base&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;event&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;event_list&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;activeq&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;NULL;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;i;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;short&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;ncalls;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&amp;nbsp;i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;nactivequeues;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;i)&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(TAILQ_FIRST(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;activequeues[i])&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;NULL)&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;一次只处理一个就绪事件链表&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;activeq&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;activequeues[i];&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assert(activeq&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;NULL);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;处理就绪事件链表上的所有事件&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(ev&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;TAILQ_FIRST(activeq);&amp;nbsp;ev;&amp;nbsp;ev&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;TAILQ_FIRST(activeq))&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;先将事件从链表上删除&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(ev&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev_events&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;EV_PERSIST)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;event_queue_remove(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;ev,&amp;nbsp;EVLIST_ACTIVE);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;event_del(ev);&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;删除事件&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;Allows&amp;nbsp;deletes&amp;nbsp;to&amp;nbsp;work&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ncalls&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;ev&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev_ncalls;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ev&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev_pncalls&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ncalls;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(ncalls)&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ncalls&lt;/span&gt;&lt;span style="color: #000000;"&gt;--&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;调用次数减1&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ev&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev_ncalls&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;ncalls;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;调用事件的回调函数&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev_callback)((&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;)ev&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev_fd,&amp;nbsp;ev&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev_res,&amp;nbsp;ev&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev_arg);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;event_break)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;41&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;42&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;43&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;44&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;45&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;4、Timer事件&lt;br /&gt;Timer事件的处理本身比较简单，不再赘述。&lt;br /&gt;&lt;br /&gt;5、signal事件&lt;br /&gt;5.1、socket pair&lt;br /&gt;Libevent通过socketpair，将signal事件与I/O事件完美的统一起来。Socketpair，简单的说就一对socket，一端用于写，一端用于读。工作方式如下：&lt;br /&gt;&lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/hustcat/2010/libevent02.JPG" height="206" width="461" /&gt;&lt;br /&gt;&amp;nbsp;为了与I/O事件统一起来，libevent内部使用了一个针对read socket的读事件。&lt;br /&gt;&lt;br /&gt;5.1.1、Socketpair的创建&lt;br /&gt;与信号事件的初始化工作都是在evsignal_init中完成的，而evsignal_init通过调用evutil_socketpair创建socketpair。对于Unix平台，有socketpair系统调用；对于Windows，则相对复杂一些，具体见evutil_socketpair函数的实现。&lt;br /&gt;&lt;br /&gt;5.2、evsignal_info&lt;br /&gt;在event_base内部有一个evsignal_info类型的字段sig，它是用于管理signal事件的核心数据结构：&lt;br /&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('be210b86-1df6-424c-bedc-f14f4b882367')"&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" class="code_img_closed" id="code_img_closed_be210b86-1df6-424c-bedc-f14f4b882367" style="display: none;" alt="" /&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" class="code_img_opened" id="code_img_opened_be210b86-1df6-424c-bedc-f14f4b882367" onclick="cnblogs_code_hide('be210b86-1df6-424c-bedc-f14f4b882367',event)"&gt;&lt;div id="cnblogs_code_open_be210b86-1df6-424c-bedc-f14f4b882367"&gt;&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;evsignal.h&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;evsignal_info&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;event&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;ev_signal;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;内部socket读事件&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;ev_signal_pair[&lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;];&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;对应socket&amp;nbsp;pair的两个socket描述符&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;ev_signal_added;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;内部socket读事件是否已经加入注册链表&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;volatile&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;sig_atomic_t&amp;nbsp;evsignal_caught;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;是否有信号发生&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;信号事件链表数组,evsigevents[signo]表示注册信号signo的事件&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;event_list&amp;nbsp;evsigevents[NSIG];&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;具体记录每个信号触发的次数，evsigcaught[signo]是记录信号&amp;nbsp;signo被触发的次数&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig_atomic_t&amp;nbsp;evsigcaught[NSIG];&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;sh_old记录了原来的&amp;nbsp;signal&amp;nbsp;处理函数指针，当信号&amp;nbsp;signo&amp;nbsp;注册的&amp;nbsp;event&amp;nbsp;被清空时，需要重新设置其处理函数&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;#ifdef&amp;nbsp;HAVE_SIGACTION&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;sigaction&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;**&lt;/span&gt;&lt;span style="color: #000000;"&gt;sh_old;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;#else&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;ev_sighandler_t&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;**&lt;/span&gt;&lt;span style="color: #000000;"&gt;sh_old;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;#endif&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;sh_old_max;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;};&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;5.3、主要函数&lt;br /&gt;5.3.1、evsignal_init&lt;br /&gt;主要完成evsignal_info的初始化，主要算法：&lt;br /&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('507e583c-4cc4-45b3-96da-469c77b399ad')"&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" class="code_img_closed" id="code_img_closed_507e583c-4cc4-45b3-96da-469c77b399ad" style="display: none;" alt="" /&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" class="code_img_opened" id="code_img_opened_507e583c-4cc4-45b3-96da-469c77b399ad" onclick="cnblogs_code_hide('507e583c-4cc4-45b3-96da-469c77b399ad',event)"&gt;&lt;div id="cnblogs_code_open_507e583c-4cc4-45b3-96da-469c77b399ad"&gt;&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;evsignal_init(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;event_base&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;evutil_socketpair(AF_UNIX,&amp;nbsp;SOCK_STREAM,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig.ev_signal_pair);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig.sh_old&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;NULL;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig.sh_old_max&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;事件发生次数设为0&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig.evsignal_caught&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;memset(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig.evsigcaught,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;sizeof&lt;/span&gt;&lt;span style="color: #000000;"&gt;(sig_atomic_t)&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;NSIG);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;initialize&amp;nbsp;the&amp;nbsp;queues&amp;nbsp;for&amp;nbsp;all&amp;nbsp;events&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&amp;nbsp;i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;NSIG;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;i)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;TAILQ_INIT(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig.evsigevents[i]);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;evutil_make_socket_nonblocking(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig.ev_signal_pair[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;]);&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;写端&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;设置内部读事件&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;event_set(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig.ev_signal,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig.ev_signal_pair[&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;],&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;EV_READ&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;EV_PERSIST,&amp;nbsp;evsignal_cb,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig.ev_signal);&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;读端&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig.ev_signal.ev_base&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;sig.ev_signal&amp;nbsp;==&amp;nbsp;EV_READ&amp;nbsp;|&amp;nbsp;EV_PERSIST&amp;nbsp;|&amp;nbsp;EVLIST_INTERNAL&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig.ev_signal.ev_flags&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;|=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;EVLIST_INTERNAL;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;span style="color: #008080;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;该函数的关键在于这里会设置libevent用于管理信号事件的内部读事件evsignal_info的ev_signal，并将该事件对应的文件描述符设为socket pair的读端。该函数由I/O multiplex的init函数调用。注：这里只是设置，而并没有注册socket pair的读事件(见下一节)。&lt;br /&gt;&lt;br /&gt;5.3.2、evsignal_add&lt;br /&gt;当调用event_add注册信号事件时，内部会先调用I/O multiplex的add函数，add函数又会调用evsignal_add，将事件加到evsignal_info内部的信号事件链表。然后再event_queue_insert将其添加到event_base的注册事件链表。&lt;br /&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('ec34fe8b-d732-4998-95d3-6a96ee37b701')"&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" class="code_img_closed" id="code_img_closed_ec34fe8b-d732-4998-95d3-6a96ee37b701" alt="" /&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" class="code_img_opened" id="code_img_opened_ec34fe8b-d732-4998-95d3-6a96ee37b701" onclick="cnblogs_code_hide('ec34fe8b-d732-4998-95d3-6a96ee37b701',event)" style="display: none;"&gt;&lt;div id="cnblogs_code_open_ec34fe8b-d732-4998-95d3-6a96ee37b701" class="cnblogs_code_hide"&gt;&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;evsignal_add(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;event&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;evsignal;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;event_base&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;ev&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev_base;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;evsignal_info&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev_base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;信号事件与I/O事件是不相容的&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(ev&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev_events&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(EV_READ&lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt;EV_WRITE))&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;event_errx(&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;%s:&amp;nbsp;EV_SIGNAL&amp;nbsp;incompatible&amp;nbsp;use&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;__func__);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;事件的信号&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;evsignal&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;EVENT_SIGNAL(ev);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assert(evsignal&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;evsignal&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;NSIG);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(TAILQ_EMPTY(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;evsigevents[evsignal]))&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;event_debug((&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;%s:&amp;nbsp;%p:&amp;nbsp;changing&amp;nbsp;signal&amp;nbsp;handler&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;__func__,&amp;nbsp;ev));&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;注册信号处理函数evsignal_handler&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;向socket&amp;nbsp;pair的写端写入一个字节的数据&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(_evsignal_set_handler(&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;evsignal,&amp;nbsp;evsignal_handler)&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;catch&amp;nbsp;signals&amp;nbsp;if&amp;nbsp;they&amp;nbsp;happen&amp;nbsp;quickly&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;evsignal_base&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;添加内部socket读事件sig-&amp;gt;ev_signal&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev_signal_added)&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(event_add(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev_signal,&amp;nbsp;NULL))&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sig&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev_signal_added&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;multiple&amp;nbsp;events&amp;nbsp;may&amp;nbsp;listen&amp;nbsp;to&amp;nbsp;the&amp;nbsp;same&amp;nbsp;signal&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;添加信号事件链表&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TAILQ_INSERT_TAIL(&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;evsigevents[evsignal],&amp;nbsp;ev,&amp;nbsp;ev_signal_next);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;这里有两个地方需要注意，一是调用_evsignal_set_handler设置外部注册信号事件对应的信号的信号处理函数evsignal_handler：&lt;br /&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('099daf3b-3739-44ad-97a1-588f1f54aedd')"&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" class="code_img_closed" id="code_img_closed_099daf3b-3739-44ad-97a1-588f1f54aedd" style="display: none;" alt="" /&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" class="code_img_opened" id="code_img_opened_099daf3b-3739-44ad-97a1-588f1f54aedd" onclick="cnblogs_code_hide('099daf3b-3739-44ad-97a1-588f1f54aedd',event)"&gt;&lt;div id="cnblogs_code_open_099daf3b-3739-44ad-97a1-588f1f54aedd"&gt;&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;evsignal_handler(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;sig)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;save_errno&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;errno;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;设置信号事件的发生次数&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;evsignal_base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig.evsigcaught[sig]&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;evsignal_base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig.evsignal_caught&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;#ifndef&amp;nbsp;HAVE_SIGACTION&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;signal(sig,&amp;nbsp;evsignal_handler);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;#endif&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;Wake&amp;nbsp;up&amp;nbsp;our&amp;nbsp;notification&amp;nbsp;mechanism&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;向socket&amp;nbsp;pair的写端写数据&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;send(evsignal_base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig.ev_signal_pair[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;],&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;a&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;errno&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;save_errno;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;span style="color: #008080;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;当用户注册信号事件对应的信号发生时，OS转到evsignal_handler函数，从而设置sig.evsignal_caught，并向socket pair的写端发送数据。&lt;br /&gt;二是通过调用event_add完成内部socket pair的读事件sig-&amp;gt;ev_signal的注册。最后，将（外部）事件添加到信号事件链表。&lt;br /&gt;5.3.2、与主循环结合&lt;br /&gt;信号事件完成了注册，libevent就会在主循环中，等待事件发生，并处理事件。为了理解，来看看具体I/O demultiplex的dispatch函数：&lt;br /&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('ac238b3e-0de0-42ff-b475-df86a78d8adc')"&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" class="code_img_closed" id="code_img_closed_ac238b3e-0de0-42ff-b475-df86a78d8adc" style="display: none;" alt="" /&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" class="code_img_opened" id="code_img_opened_ac238b3e-0de0-42ff-b475-df86a78d8adc" onclick="cnblogs_code_hide('ac238b3e-0de0-42ff-b475-df86a78d8adc',event)"&gt;&lt;div id="cnblogs_code_open_ac238b3e-0de0-42ff-b475-df86a78d8adc"&gt;&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;epoll_dispatch(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;event_base&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;arg,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;timeval&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;tv)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;epollop&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;epollop&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;arg;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;epoll_event&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;events&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;epollop&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;events;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;struct&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;evepoll&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;evep;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;i,&amp;nbsp;res,&amp;nbsp;timeout&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(tv&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;NULL)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;timeout&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;tv&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;tv_sec&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;1000&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(tv&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;tv_usec&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;999&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;1000&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(timeout&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;MAX_EPOLL_TIMEOUT_MSEC)&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;Linux&amp;nbsp;kernels&amp;nbsp;can&amp;nbsp;wait&amp;nbsp;forever&amp;nbsp;if&amp;nbsp;the&amp;nbsp;timeout&amp;nbsp;is&amp;nbsp;too&amp;nbsp;big;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*&amp;nbsp;see&amp;nbsp;comment&amp;nbsp;on&amp;nbsp;MAX_EPOLL_TIMEOUT_MSEC.&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;timeout&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;MAX_EPOLL_TIMEOUT_MSEC;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;等待I/O事件&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;epoll_wait(epollop&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;epfd,&amp;nbsp;events,&amp;nbsp;epollop&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;nevents,&amp;nbsp;timeout);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(res&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(errno&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;EINTR)&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;event_warn(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;epoll_wait&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;epoll_wait被信号中断&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;evsignal_process(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;sig.evsignal_caught)&amp;nbsp;{&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;发生了信号事件&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;处理信号事件&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;evsignal_process(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;#8230;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;epoll_dispatch函数调用epoll_wait函数等待I/O发生。然后，如果有信号事件发生，则调用evsignal_process处理信号事件，evsignal_process的逻辑比较简单，它只是将事件从注册事件链表转移到就绪事件链表。&lt;br /&gt;&lt;br /&gt;还记得evsignal_handler函数吗？它是所有（外部）信号事件对应的信号的信号处理函数，将实际的信号发生时，OS会转而执行evsignal_handler函数，而它便向socket pair的写端写数据，而读端收到数据。而此时，libevent的内部socket pair读事件已经完成注册。libevent正阻塞在epoll_wait处，当socketp pair读端收到数据时，libevent便从epoll_wait处返回。总之，signal事件通过socket pair，与I/O事件实现完美的统一。&lt;br /&gt;&lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/hustcat/2010/libevent03.JPG" height="244" width="554" /&gt;&lt;br /&gt;Libevent从epoll_wait返回后，它调用evsignal_process处理信号事件，然后调用event_active将I/O事件（包括内部的socket pair读事件）转移到就绪事件链表。&lt;br /&gt;&lt;br /&gt;Socket pair的读事件回调函数：&lt;br /&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('615b8bbc-c176-4198-91d0-ba7231911fc3')"&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" class="code_img_closed" id="code_img_closed_615b8bbc-c176-4198-91d0-ba7231911fc3" style="display: none;" alt="" /&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" class="code_img_opened" id="code_img_opened_615b8bbc-c176-4198-91d0-ba7231911fc3" onclick="cnblogs_code_hide('615b8bbc-c176-4198-91d0-ba7231911fc3',event)"&gt;&lt;div id="cnblogs_code_open_615b8bbc-c176-4198-91d0-ba7231911fc3"&gt;&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;evsignal_cb(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;fd,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;short&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;what,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt;arg)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;char&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;signals[&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;];&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;#ifdef&amp;nbsp;WIN32&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;SSIZE_T&amp;nbsp;n;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;#else&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;ssize_t&amp;nbsp;n;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;#endif&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;接收数据&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;n&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;recv(fd,&amp;nbsp;signals,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;sizeof&lt;/span&gt;&lt;span style="color: #000000;"&gt;(signals),&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(n&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;event_err(&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;%s:&amp;nbsp;read&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;__func__);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;6、libevent的应用&lt;br /&gt;Libevent是一个非常优秀的开源网络库，它被许多其它开源程序使用。Memcache使用libevent作为底层的网络处理组件，并采用主线程(main thread，单一)+工作线程(work thread，多个)的多线程模型（这将在Memcached的分析中详细介绍）。&lt;br /&gt;&lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/hustcat/2010/libevent04.JPG" height="410" width="521" /&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;div id="AllanboltSignature"&gt;  &lt;p id="PSignature"&gt;&lt;br /&gt;作者：&lt;a href="http://www.cnblogs.com/hustcat/" target="_blank"&gt;arrowcat&lt;/a&gt; &lt;br /&gt;出处：&lt;a href="http://www.cnblogs.com/hustcat/" target="_blank"&gt;http://www.cnblogs.com/hustcat/&lt;/a&gt; &lt;br /&gt;本文版权归作者和博客园共有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。 &lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/hustcat/aggbug/1814022.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hustcat/archive/2010/08/31/1814022.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hustcat/archive/2010/07/29/1788179.html</id><title type="text">vim7.2中文乱码解决方法</title><summary type="text">vim7.2中文乱码解决方法</summary><published>2010-07-29T11:42:00Z</published><updated>2010-07-29T11:42:00Z</updated><author><name>MrDB</name><uri>http://www.cnblogs.com/hustcat/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hustcat/archive/2010/07/29/1788179.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hustcat/archive/2010/07/29/1788179.html"/><content type="html">&lt;p&gt; 这个问题困扰我几天了。网上查了许久，由于说得不到位，一直没解决，今天又折腾了一下，终于搞定。&lt;/p&gt;&lt;p&gt;1、下载&lt;/p&gt;&lt;p&gt;可到http://www.vim.org/下载最新的7.2。&lt;/p&gt;&lt;p&gt;2、安装&lt;/p&gt;&lt;p&gt;编译之前，先要configure --help查看一下配置选项， &lt;br /&gt;--enable-multibyte&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Include multibyte editing support.&amp;nbsp;&lt;/p&gt;&lt;p&gt;支持多字节编码，这一步很重要。否则，后面如何配置也是枉然。&lt;/p&gt;&lt;p&gt;然后，&lt;br /&gt;[root@localhost wbl]# vim --version | grep multi&lt;br /&gt;-mouse_jsbterm -mouse_netterm -mouse_sysmouse +mouse_xterm &lt;span style="color: red;"&gt;+multi_byte&lt;/span&gt;&lt;br /&gt;+multi_lang -mzscheme +netbeans_intg -osfiletype +path_extra -perl +postscript&lt;br /&gt;查看配置是否起作用。&lt;/p&gt;&lt;p&gt;&amp;nbsp;3、配置&lt;/p&gt;&lt;p&gt;编辑~/.vimrc文件，加上如下几行：&lt;/p&gt;&lt;p&gt;set fileencodings=gb2312,gb18030,utf-8&lt;br /&gt;set termencoding=utf-8&lt;br /&gt;set encoding=prc&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;即可搞定。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;附(Vim编码详细介绍)：&lt;/p&gt;&lt;p&gt;Vim和所有的流行文本编辑器一样，Vim 可以很好的编辑各种字符编码的文件，这当然包括 UCS-2、UTF-8 等流行的 Unicode 编码方式。&lt;br /&gt;&lt;br /&gt;Vim 有四个跟字符编码方式有关的选项，encoding、fileencoding、fileencodings、termencoding (这些选项可能的取值请参考 Vim 在线帮助 :help encoding-names)，它们的意义如下:&lt;br /&gt;(1)encoding: Vim 内部使用的字符编码方式，包括 Vim 的 buffer (缓冲区)、菜单文本、消息文本等。用户手册上建议只在 .vimrc 中改变它的值，事实上似乎也只有在 .vimrc 中改变它的值才有意义。&lt;br /&gt;(2)fileencoding: Vim 中当前编辑的文件的字符编码方式，Vim 保存文件时也会将文件保存为这种字符编码方式 (不管是否新文件都如此)。&lt;br /&gt;(3)fileencodings: Vim 启动时会按照它所列出的字符编码方式逐一探测即将打开的文件的字符编码方式，并且将 fileencoding 设置为最终探测到的字符编码方式。因此最好将 Unicode 编码方式放到这个列表的最前面，将拉丁语系编码方式 latin1 放到最后面。&lt;br /&gt;(4)ermencoding: Vim 所工作的终端 (或者 Windows 的 Console 窗口) 的字符编码方式。这个选项在 Windows 下对我们常用的 GUI 模式的 gVim 无效，而对 Console 模式的 Vim 而言就是 Windows 控制台的代码页，并且通常我们不需要改变它。&lt;br /&gt;&lt;br /&gt;来看看 Vim 的多字符编码方式支持是如何工作的。&lt;br /&gt;(1)Vim 启动，根据 .vimrc 中设置的 encoding 的值来设置 buffer、菜单文本、消息文的字符编码方式。&lt;br /&gt;(2)读取需要编辑的文件，根据 fileencodings 中列出的字符编码方式逐一探测该文件编码方式。并设置 fileencoding 为探测到的，看起来是正确的 (注1) 字符编码方式。&lt;br /&gt;(3)对比 fileencoding 和 encoding 的值，若不同则调用 iconv 将文件内容转换为 encoding 所描述的字符编码方式，并且把转换后的内容放到为此文件开辟的 buffer 里，此时我们就可以开始编辑这个文件了。注意，完成这一步动作需要调用外部的 iconv.dll (注2)，你需要保证这个文件存在于 $VIMRUNTIME 或者其他列在 PATH 环境变量中的目录里。&lt;br /&gt;(4)编辑完成后保存文件时，再次对比 fileencoding 和 encoding 的值。若不同，再次调用 iconv 将即将保存的 buffer 中的文本转换为 fileencoding 所描述的字符编码方式，并保存到指定的文件中。同样，这需要调用 iconv.dll&lt;br /&gt;&lt;br /&gt;由于 Unicode 能够包含几乎所有的语言的字符，而且 Unicode 的 UTF-8 编码方式又是非常具有性价比的编码方式 (空间消耗比 UCS-2 小)，因此建议 encoding 的值设置为 utf-8。这么做的另一个理由是 encoding 设置为 utf-8 时，Vim 自动探测文件的编码方式会更准确 (或许这个理由才是主要的 ;) 。我们在中文 Windows 里编辑的文件，为了兼顾与其他软件的兼容性，文件编码还是设置为 GB2312/GBK 比较合适，因此 fileencoding 建议设置为 chinese (chinese 是个别名，在 Unix 里表示 gb2312，在 Windows 里表示 cp936，也就是 GBK 的代码页)。&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/hustcat/aggbug/1788179.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hustcat/archive/2010/07/29/1788179.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hustcat/archive/2010/07/22/1782969.html</id><title type="text">SlickEdit的破解</title><summary type="text">SlickEdit破解方法</summary><published>2010-07-22T04:55:00Z</published><updated>2010-07-22T04:55:00Z</updated><author><name>MrDB</name><uri>http://www.cnblogs.com/hustcat/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hustcat/archive/2010/07/22/1782969.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hustcat/archive/2010/07/22/1782969.html"/><content type="html">&lt;p&gt;SlickEdit是一个非常不错的编辑器，相对于SI，更有开发环境的味道。不过，相对于Vim，它们都是收费的。在公司购买的正版软件列表上没有找到，&lt;/p&gt;&lt;p&gt;只好下载一个，破解之。 &lt;br /&gt;&lt;/p&gt;&lt;p&gt;下载： &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a title="http://www.slickedit.com/trial/slickedit" href="http://www.slickedit.com/trial/slickedit"&gt;http://www.slickedit.com/trial/slickedit&lt;/a&gt;&lt;/p&gt;&lt;p&gt;安装后，需要授权文件。&lt;/p&gt;&lt;p&gt;先不管它，下面用hiew&amp;#8212;&amp;#8212;强大的反汇编工具，来破解win/vs.exe。 &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;gt;hiew32 vs.exe&lt;br /&gt;&lt;/p&gt;&lt;p&gt;按两次&amp;lt;Enter&amp;gt;，进入汇编模式。&lt;/p&gt;&lt;p&gt;按&amp;lt;F5&amp;gt;，输入F750，转到0040F750处；&lt;/p&gt;&lt;p&gt;按&amp;lt;F3&amp;gt;，切换在编辑模式，&lt;/p&gt;&lt;p&gt;将 mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, ebp&amp;nbsp; 改成&amp;nbsp; xor eax,eax ；&lt;/p&gt;&lt;p&gt;&lt;img alt="" src="http://images.cnblogs.com/cnblogs_com/hustcat/2010/slickedit1.JPG" height="400" width="644" /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;回车，按&amp;lt;F9&amp;gt;保存，两分钟搞定。&lt;/p&gt;&lt;p&gt;再运行SlickEdit，不再出现授权界面。 &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &lt;br /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/hustcat/aggbug/1782969.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hustcat/archive/2010/07/22/1782969.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hustcat/archive/2010/07/01/1769219.html</id><title type="text">Hbase初体验</title><summary type="text">HBase使用入门</summary><published>2010-07-01T07:38:00Z</published><updated>2010-07-01T07:38:00Z</updated><author><name>MrDB</name><uri>http://www.cnblogs.com/hustcat/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hustcat/archive/2010/07/01/1769219.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hustcat/archive/2010/07/01/1769219.html"/><content type="html">&lt;p&gt;1、配置&lt;/p&gt;&lt;p&gt;(1)编辑$HBASE_HOME/conf/ hbase-env.sh配置环境变量JAVA_HOME;&lt;/p&gt;&lt;p&gt;(2)编辑$HBASE_HOME/conf/hbase-site.xml, 增加如下配置(与Hadoop保持一致)：&lt;/p&gt;&lt;p&gt;&amp;lt;property&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;name&amp;gt;hbase.rootdir&amp;lt;/name&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;hdfs://localhost:9000/hbase&amp;lt;/value&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;description&amp;gt;The directory shared by region servers.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/description&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;/property&amp;gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;2、使用&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;#启动HBase&lt;br /&gt;[root@yy1 hbase-0.20.5]# bin/start-hbase.sh&lt;br /&gt;localhost: starting zookeeper, logging to /root/hadoop/hbase-0.20.5/bin/../logs/hbase-root-zookeeper-yy1.out&lt;br /&gt;starting master, logging to /root/hadoop/hbase-0.20.5/bin/../logs/hbase-root-master-yy1.out&lt;br /&gt;localhost: starting regionserver, logging to /root/hadoop/hbase-0.20.5/bin/../logs/hbase-root-regionserver-yy1.out&lt;/p&gt;&lt;p&gt;[root@yy1 hbase-0.20.5]# bin/hbase shell&lt;br /&gt;HBase Shell; enter 'help&amp;lt;RETURN&amp;gt;' for list of supported commands.&lt;br /&gt;Version: 0.20.5, r956266, Sat Jun 19 12:25:12 PDT 2010&lt;br /&gt;hbase(main):001:0&amp;gt; &lt;/p&gt;&lt;p&gt;#创建表test&lt;br /&gt;hbase(main):003:0&amp;gt; create "test","data"&lt;br /&gt;0 row(s) in 1.3560 seconds&lt;br /&gt;hbase(main):004:0&amp;gt; describe "test"&lt;br /&gt;DESCRIPTION&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ENABLED&lt;br /&gt;&amp;nbsp;{NAME =&amp;gt; 'test', FAMILIES =&amp;gt; [{NAME =&amp;gt; 'data', COMPRESSION =&amp;gt; 'NONE',&amp;nbsp; true&lt;br /&gt;&amp;nbsp;VERSIONS =&amp;gt; '3', TTL =&amp;gt; '2147483647', BLOCKSIZE =&amp;gt; '65536', IN_MEMORY&lt;br /&gt;&amp;nbsp;=&amp;gt; 'false', BLOCKCACHE =&amp;gt; 'true'}]}&lt;br /&gt;1 row(s) in 0.0610 seconds&lt;/p&gt;&lt;p&gt;#插入数据&lt;br /&gt;hbase(main):005:0&amp;gt; put "test","row1","data:1","value1"&lt;br /&gt;0 row(s) in 0.0060 seconds&lt;br /&gt;hbase(main):006:0&amp;gt; put "test","row2","data:2","value2"&lt;br /&gt;0 row(s) in 0.0100 seconds&lt;br /&gt;hbase(main):007:0&amp;gt; scan "test"&lt;br /&gt;ROW&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; COLUMN+CELL&lt;br /&gt;&amp;nbsp;row1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; column=data:1, timestamp=1277968472718, value=value1&lt;br /&gt;&amp;nbsp;row2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; column=data:2, timestamp=1277968487913, value=value2&lt;br /&gt;2 row(s) in 0.0350 seconds&lt;/p&gt;&lt;p&gt;hbase(main):009:0&amp;gt; get "test", "row1"&lt;br /&gt;COLUMN&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CELL&lt;br /&gt;&amp;nbsp;data:1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; timestamp=1277968472718, value=value1&lt;br /&gt;1 row(s) in 0.0100 seconds&lt;/p&gt;&lt;p&gt;#停止HBase&lt;br /&gt;[root@yy1 hbase-0.20.5]# bin/stop-hbase.sh&lt;br /&gt;stopping master..............................&lt;br /&gt;localhost: stopping zookeeper.&lt;/p&gt;&lt;p&gt;#HBase创建的文件&lt;br /&gt;[root@yy1 hadoop-0.20.2]# bin/hadoop fs -ls /hbase&lt;br /&gt;Found 5 items&lt;br /&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp; - root supergroup&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 2010-07-01 14:51 /hbase/-ROOT-&lt;br /&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp; - root supergroup&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 2010-07-01 14:51 /hbase/.META.&lt;br /&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp; - root supergroup&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 2010-07-01 15:18 /hbase/.logs&lt;br /&gt;-rw-r--r--&amp;nbsp;&amp;nbsp; 3 root supergroup&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3 2010-07-01 14:51 /hbase/hbase.version&lt;br /&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp; - root supergroup&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 2010-07-01 15:12 /hbase/test&lt;br /&gt;[root@yy1 hadoop-0.20.2]# bin/hadoop fs -ls /hbase/test&lt;br /&gt;Found 1 items&lt;br /&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp; - root supergroup&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 2010-07-01 15:18 /hbase/test/1886847087&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;img src="http://www.cnblogs.com/hustcat/aggbug/1769219.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hustcat/archive/2010/07/01/1769219.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hustcat/archive/2010/06/30/1768506.html</id><title type="text">Hadoop初体验——问题总结</title><summary type="text">Hadoop常见问题小结</summary><published>2010-06-30T09:22:00Z</published><updated>2010-06-30T09:22:00Z</updated><author><name>MrDB</name><uri>http://www.cnblogs.com/hustcat/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hustcat/archive/2010/06/30/1768506.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hustcat/archive/2010/06/30/1768506.html"/><content type="html">&lt;p&gt;第一次使用Hadoop，整个过程真是让我折腾。&lt;/p&gt;&lt;p&gt;先是在cygwin下，出现如下问题：&lt;/p&gt;&lt;p&gt;&lt;span class="t_tag" onclick="tagshow(event)" href="tag.php?name=cygwin"&gt;cygwin&lt;/span&gt;&amp;nbsp; &amp;nbsp; :1.7.5-1&lt;br /&gt;openssh :5.5p1-2&lt;br /&gt;openssl&amp;nbsp;&amp;nbsp;:0.9.8o-2&lt;br /&gt;&lt;br /&gt;ssh已经配置，且在cygwin下输入：&lt;br /&gt;net start sshd&lt;br /&gt;显示成功启动&lt;br /&gt;&lt;br /&gt;然后输入，&lt;br /&gt;ssh localhost&lt;br /&gt;此时，没有任何输出，一直挂着。&lt;br /&gt;&lt;br /&gt;事件查看器输出如下&lt;span class="t_tag" onclick="tagshow(event)" href="tag.php?name=%B4%ED%CE%F3"&gt;错误&lt;/span&gt;：&lt;br /&gt;sshd: PID 632: error: setsockopt IPV6_V6ONLY: Protocol not available.&lt;br /&gt;似乎是sshd内部调用setsockopt设置IPV6_V6ONLY出错。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;搞了很久，也没搞好。只好做罢，在vmware中又遇到各种问题：&lt;/p&gt;&lt;p&gt;1、safemode&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #000000"&gt;bin&lt;/span&gt;&lt;span style="color: #000000"&gt;/&lt;/span&gt;&lt;span style="color: #000000"&gt;hadoop&amp;nbsp;fs&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;-&lt;/span&gt;&lt;span style="color: #000000"&gt;put&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;./&lt;/span&gt;&lt;span style="color: #000000"&gt;input&amp;nbsp;input&lt;br /&gt;put&lt;/span&gt;&lt;span style="color: #000000"&gt;:&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;org&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;apache&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;hadoop&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;hdfs&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;server&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;namenode&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;SafeModeException&lt;/span&gt;&lt;span style="color: #000000"&gt;:&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Cannot&amp;nbsp;create&amp;nbsp;directory&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;/&lt;/span&gt;&lt;span style="color: #000000"&gt;user&lt;/span&gt;&lt;span style="color: #000000"&gt;/&lt;/span&gt;&lt;span style="color: #000000"&gt;root&lt;/span&gt;&lt;span style="color: #000000"&gt;/&lt;/span&gt;&lt;span style="color: #000000"&gt;input&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Name&amp;nbsp;node&amp;nbsp;is&amp;nbsp;in&amp;nbsp;safe&amp;nbsp;mode&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;解决方法：&lt;/p&gt;&lt;p&gt;NameNode在启动的时候首先进入安全模式，如果datanode丢失的block达到一定的比例（1-dfs.safemode.threshold.pct），则系统会一直处于安全模式状态即只读状态。&lt;/p&gt;&lt;p&gt;dfs.safemode.threshold.pct（缺省值0.999f）表示HDFS启动的时候，如果DataNode上报的block个数达到了元数据记录的block个数的0.999倍才可以离开安全模式，否则一直是这种只读模式。如果设为1则HDFS永远是处于SafeMode。&lt;/p&gt;&lt;p&gt;下面这行摘录自NameNode启动时的日志（block上报比例1达到了阀值0.9990）&lt;/p&gt;&lt;p&gt;The ratio of reported blocks 1.0000 has reached the threshold 0.9990. Safe mode will be turned off automatically in 18 seconds.&lt;br /&gt;hadoop dfsadmin -safemode leave&lt;/p&gt;&lt;p&gt;有两个方法离开这种安全模式&lt;br /&gt;（1）修改dfs.safemode.threshold.pct为一个比较小的值，缺省是0.999。&lt;br /&gt;（2）hadoop dfsadmin -safemode leave命令强制离开&lt;/p&gt;&lt;p&gt;用户可以通过dfsadmin -safemode value&amp;nbsp; 来操作安全模式，参数value的说明如下：&lt;/p&gt;&lt;p&gt;enter - 进入安全模式&lt;br /&gt;leave - 强制NameNode离开安全模式&lt;br /&gt;get -&amp;nbsp; 返回安全模式是否开启的信息&lt;br /&gt;wait - 等待，一直到安全模式结束。&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;2、could only be replicated to 0 nodes, instead of 1&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #000000"&gt;#执行 fs -put时，出现如下问题&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="color: #000000"&gt;hdfs&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;DFSClient&lt;/span&gt;&lt;span style="color: #000000"&gt;:&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;DataStreamer&amp;nbsp;Exception&lt;/span&gt;&lt;span style="color: #000000"&gt;:&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;org&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;apache&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;hadoop&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;ipc&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;RemoteException&lt;/span&gt;&lt;span style="color: #000000"&gt;:&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;java&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;io&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;IOException&lt;/span&gt;&lt;span style="color: #000000"&gt;:&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;...&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;could&amp;nbsp;only&amp;nbsp;be&amp;nbsp;replicated&amp;nbsp;to&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;nodes&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;instead&amp;nbsp;of&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;解决方法：&lt;br /&gt;（1）防火墙原因&lt;br /&gt;（2）磁盘空间原因&lt;br /&gt;df &amp;#8211;ah&amp;nbsp; #查看磁盘空间&lt;br /&gt;如果是磁盘空间不够，则调整磁盘空间(我就是该原因，折腾了很久)，推荐一个强大的分区工具&lt;a title="GParted " href="http://gparted.sourceforge.net/" target="_blank"&gt;GParted &lt;/a&gt;。&lt;br /&gt;&lt;/p&gt;&lt;p&gt;3、DataNode error &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('2f1adc44-6f23-4896-bccd-1bcb263e6e08')"&gt;&lt;img style="display: none" id="code_img_closed_2f1adc44-6f23-4896-bccd-1bcb263e6e08" class="code_img_closed" alt="" src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" /&gt;&lt;img id="code_img_opened_2f1adc44-6f23-4896-bccd-1bcb263e6e08" class="code_img_opened" onclick="cnblogs_code_hide('2f1adc44-6f23-4896-bccd-1bcb263e6e08',event)" src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif"&gt; &lt;div id="cnblogs_code_open_2f1adc44-6f23-4896-bccd-1bcb263e6e08"&gt;&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #800000"&gt;2010&lt;/span&gt;&lt;span style="color: #000000"&gt;-&lt;/span&gt;&lt;span style="color: #800000"&gt;06&lt;/span&gt;&lt;span style="color: #000000"&gt;-&lt;/span&gt;&lt;span style="color: #800000"&gt;25&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000"&gt;11&lt;/span&gt;&lt;span style="color: #000000"&gt;:&lt;/span&gt;&lt;span style="color: #800000"&gt;40&lt;/span&gt;&lt;span style="color: #000000"&gt;:&lt;/span&gt;&lt;span style="color: #800000"&gt;12&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #800000"&gt;473&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;ERROR&amp;nbsp;org&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;apache&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;hadoop&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;hdfs&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;server&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;datanode&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;DataNode&lt;/span&gt;&lt;span style="color: #000000"&gt;:&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;java&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;io&lt;/span&gt;&lt;span style="color: #000000"&gt;.&lt;/span&gt;&lt;span style="color: #000000"&gt;IOException&lt;/span&gt;&lt;span style="color: #000000"&gt;:&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Incompatible&amp;nbsp;namespaceIDs&amp;nbsp;in&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;/&lt;/span&gt;&lt;span style="color: #000000"&gt;tmp&lt;/span&gt;&lt;span style="color: #000000"&gt;/&lt;/span&gt;&lt;span style="color: #000000"&gt;hadoop&lt;/span&gt;&lt;span style="color: #000000"&gt;-&lt;/span&gt;&lt;span style="color: #000000"&gt;root&lt;/span&gt;&lt;span style="color: #000000"&gt;/&lt;/span&gt;&lt;span style="color: #000000"&gt;dfs&lt;/span&gt;&lt;span style="color: #000000"&gt;/&lt;/span&gt;&lt;span style="color: #000000"&gt;data&lt;/span&gt;&lt;span style="color: #000000"&gt;:&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;namenode&amp;nbsp;namespaceID&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000"&gt;647870650&lt;/span&gt;&lt;span style="color: #000000"&gt;;&amp;nbsp;datanode&amp;nbsp;namespaceID&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000"&gt;466015089&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;解决方法：&lt;/p&gt;&lt;p&gt;删除 /tmp/hadoop-root/dfs目录下的所有目录，&lt;br /&gt;执行hadoop namenode -format&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;很久没有用过Java了，原以为以后不会再有机会使用。但是，有Hadoop这样优秀的开源项目，不得不又重新拾起Java。&lt;/p&gt; &lt;img src="http://www.cnblogs.com/hustcat/aggbug/1768506.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hustcat/archive/2010/06/30/1768506.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
