﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-Sheppard Y-随笔分类-c++</title><link>http://www.cppblog.com/yangsf5/category/8886.html</link><description>keep thinking keep coding.</description><language>zh-cn</language><lastBuildDate>Sun, 10 Jul 2016 22:20:17 GMT</lastBuildDate><pubDate>Sun, 10 Jul 2016 22:20:17 GMT</pubDate><ttl>60</ttl><item><title>TopN动态排行榜实现</title><link>http://www.cppblog.com/yangsf5/archive/2013/07/12/201725.html</link><dc:creator>Sheppard Y</dc:creator><author>Sheppard Y</author><pubDate>Fri, 12 Jul 2013 05:05:00 GMT</pubDate><guid>http://www.cppblog.com/yangsf5/archive/2013/07/12/201725.html</guid><wfw:comment>http://www.cppblog.com/yangsf5/comments/201725.html</wfw:comment><comments>http://www.cppblog.com/yangsf5/archive/2013/07/12/201725.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yangsf5/comments/commentRss/201725.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yangsf5/services/trackbacks/201725.html</trackback:ping><description><![CDATA[<p>&nbsp; &nbsp; &#8203;目前只是简单的封装了stl的heap相关算法：</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&#8203;<a href="https://github.com/yangsf5/claw-gse/blob/master/src/claw/gse/top_n.h">https://github.com/yangsf5/claw-gse/blob/master/src/claw/gse/top_n.h</a></p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&#8203;&#8203;</p><img src ="http://www.cppblog.com/yangsf5/aggbug/201725.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yangsf5/" target="_blank">Sheppard Y</a> 2013-07-12 13:05 <a href="http://www.cppblog.com/yangsf5/archive/2013/07/12/201725.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>protobuf与shared memory</title><link>http://www.cppblog.com/yangsf5/archive/2013/06/26/201309.html</link><dc:creator>Sheppard Y</dc:creator><author>Sheppard Y</author><pubDate>Tue, 25 Jun 2013 16:03:00 GMT</pubDate><guid>http://www.cppblog.com/yangsf5/archive/2013/06/26/201309.html</guid><wfw:comment>http://www.cppblog.com/yangsf5/comments/201309.html</wfw:comment><comments>http://www.cppblog.com/yangsf5/archive/2013/06/26/201309.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yangsf5/comments/commentRss/201309.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yangsf5/services/trackbacks/201309.html</trackback:ping><description><![CDATA[<div></div><fieldset><legend><span style="color: #ff0000;">2016-07-08 日更新&nbsp;</span></legend><div><span style="color:red;">此篇博客已经迁移到新博客，并做行文检查和优化排版：</span></div><div></div><a href="http://blog.clawz.me/2013/06/26/13-protobuf-shared-memory/"><div><span style="color:red;">http://blog.clawz.me/2013/06/26/13-protobuf-shared-memory/</span></div></a></fieldset><a href="http://blog.clawz.me/2013/06/26/13-protobuf-shared-memory/"><div></div><p>&nbsp;</p></a><p><br />&nbsp; &nbsp; &#8203;项目里shared  memory存放的数据结构，现在需要将其同时用于server与client之间的相应数据交互。server与client之前的协议格式为protobuf。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&#8203;为了只维护一份代码，准备将之前用于shared  memory的结构转化为protobuf，然后两处都用这个protobuf。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&#8203;搞了一会儿，才想起shared memory里只适合存定长的非指针结构。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&#8203;汗，这个几年前就经历过，那个时候是学生时代做五子棋世界的时候，貌似是想往shared  memory里存放std::map。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&#8203;当时水平太低，报错了就放弃了stl的容器，写些了中规中矩的结构体。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&#8203;这次就顺便搜下当年那个问题的解决方法。找到个说的挺好的：<a href="http://www.cnblogs.com/fullsail/archive/2013/01/20/2868898.html" _href="http://www.cnblogs.com/fullsail/archive/2013/01/20/2868898.html">http://www.cnblogs.com/fullsail/archive/2013/01/20/2868898.html</a>。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&#8203;大意就是，stl里容器会动态分配内存，而且new的东西在自己的进程空间里，别的进程访问时必然是个不对的指针。需要将stl的分配器定制为从共享内存里分配空间，或者其他几个链接里提到的方法。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&#8203;回到我现在遇到的protobuf这个问题，protobuf里有些如repeated或者string等会动态new，这个如果做内存分配的定制，还得重改protobuf的代码，复杂度比较高。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&#8203;加上项目里的这单个协议格式制定的需求只是临时的，就更没必要了。最终放弃protobuf结构直接映射到共享内存的企图。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&#8203;</p><img src ="http://www.cppblog.com/yangsf5/aggbug/201309.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yangsf5/" target="_blank">Sheppard Y</a> 2013-06-26 00:03 <a href="http://www.cppblog.com/yangsf5/archive/2013/06/26/201309.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【msvc调试】客户端某个流程后server卡住</title><link>http://www.cppblog.com/yangsf5/archive/2013/06/21/201196.html</link><dc:creator>Sheppard Y</dc:creator><author>Sheppard Y</author><pubDate>Fri, 21 Jun 2013 04:40:00 GMT</pubDate><guid>http://www.cppblog.com/yangsf5/archive/2013/06/21/201196.html</guid><wfw:comment>http://www.cppblog.com/yangsf5/comments/201196.html</wfw:comment><comments>http://www.cppblog.com/yangsf5/archive/2013/06/21/201196.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yangsf5/comments/commentRss/201196.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yangsf5/services/trackbacks/201196.html</trackback:ping><description><![CDATA[<div></div><fieldset><legend><span style="color: #ff0000;">2016-07-08 日更新&nbsp;</span></legend><div><span style="color:red;">此篇博客已经迁移到新博客，并做行文检查和优化排版：</span></div><div></div><a href="http://blog.clawz.me/2013/06/21/13-debug-server-hang/"><div><span style="color:red;">http://blog.clawz.me/2013/06/21/13-debug-server-hang/</span></div></a></fieldset><a href="http://blog.clawz.me/2013/06/21/13-debug-server-hang/"><div></div><p>&nbsp;</p></a><p><br /><br />&nbsp;&nbsp;&nbsp;单步到崩溃地点，有数组取数据和拷贝操作，猜测数组越界导致的栈溢出。就开始找越界检查工具。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;vs自身带的/GS只是在栈溢出时蹦个异常，不会给你定位崩在哪。所以找了会儿别的工具，boundschecker还没找到下的地方，IBM的purify跨平台但是收费，另外免费好用的就是linux下的valgrind了。这几种内存检查工具都可以检查内存泄露和越界之类的。只是项目现在赶进度，linux平台的编译还没时间解决，内存统一检查就作罢。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;开始看看能不能查dump。dump不是原生的dmp而是历史代码里重存为别的了。vc调试不很熟练，就索性把重存dump那块儿的catch给干掉了。直接让编译器崩到代码块儿再看看能不能看出什么问题。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;崩停到具体代码行了，很惊喜，赶紧看看各变量内存状况，问题数组是一个指针数组，这次惊喜的发现之前单步的那个下标对应在数组元素指针跟别的不一样，为0xcdcdcdcd，确认了下为vc下为未初始化的指针。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;这样就好查了，问题定位到了，后边的就不啰嗦了。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;最终问题是，同事给一个类新加了几个指针成员，但是这几个没有new出来初始化之。唉&#8230;&#8230;只能感叹下敏捷开发那本书里说的，架构师要参加编码，我觉得要加点儿，就是架构师要参与编码还要参与测试调试自己的代码。</p><img src ="http://www.cppblog.com/yangsf5/aggbug/201196.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yangsf5/" target="_blank">Sheppard Y</a> 2013-06-21 12:40 <a href="http://www.cppblog.com/yangsf5/archive/2013/06/21/201196.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【msvc调试】server初始化时卡在某个点</title><link>http://www.cppblog.com/yangsf5/archive/2013/06/21/201195.html</link><dc:creator>Sheppard Y</dc:creator><author>Sheppard Y</author><pubDate>Fri, 21 Jun 2013 04:38:00 GMT</pubDate><guid>http://www.cppblog.com/yangsf5/archive/2013/06/21/201195.html</guid><wfw:comment>http://www.cppblog.com/yangsf5/comments/201195.html</wfw:comment><comments>http://www.cppblog.com/yangsf5/archive/2013/06/21/201195.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yangsf5/comments/commentRss/201195.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yangsf5/services/trackbacks/201195.html</trackback:ping><description><![CDATA[<div></div><fieldset><legend><span style="color: #ff0000;">2016-07-08 日更新&nbsp;</span></legend><div><span style="color:red;">此篇博客已经迁移到新博客，并做行文检查和优化排版：</span></div><div></div><a href="http://blog.clawz.me/2013/06/21/13-vc-debug-while/"><div><span style="color:red;">http://blog.clawz.me/2013/06/21/13-vc-debug-while/</span></div></a></fieldset><a href="http://blog.clawz.me/2013/06/21/13-vc-debug-while/"><div></div><p>&nbsp;</p></a><p><br />&nbsp;&nbsp;&nbsp;&nbsp;初步调试，发现某个类的构造函数进了，但是在左花括号的地方就卡住了，没有往后走。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;一开始挺惊奇，过会儿就想到，类的构造函数里会被编译器插入一些没有显示初始化的成员的初始化语句。所以讲F10改为F11调试。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;慢慢似乎找到问题函数了，正准备再重开调试继续跟时，朋友表示按下vc的暂停键，照做，&#8220;我擦&#8212;&#8212;&#8221;之后是崇拜的口水。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;问题原因：while的退出变量没有自增，导致死循环了。<br /><br /></p> <p>&nbsp;&nbsp;&nbsp;&nbsp;总结：</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;程序卡在哪儿，基本就是死循环或者死锁。死循环的发现，可以看cpu占用来佐证。问题定位，暂停调试。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;死锁的定位，可以看stack，里边应该有wait之类的。</p><img src ="http://www.cppblog.com/yangsf5/aggbug/201195.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yangsf5/" target="_blank">Sheppard Y</a> 2013-06-21 12:38 <a href="http://www.cppblog.com/yangsf5/archive/2013/06/21/201195.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>X项目C++服务器（1）- 总体构想</title><link>http://www.cppblog.com/yangsf5/archive/2013/04/25/199704.html</link><dc:creator>Sheppard Y</dc:creator><author>Sheppard Y</author><pubDate>Thu, 25 Apr 2013 06:52:00 GMT</pubDate><guid>http://www.cppblog.com/yangsf5/archive/2013/04/25/199704.html</guid><wfw:comment>http://www.cppblog.com/yangsf5/comments/199704.html</wfw:comment><comments>http://www.cppblog.com/yangsf5/archive/2013/04/25/199704.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yangsf5/comments/commentRss/199704.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yangsf5/services/trackbacks/199704.html</trackback:ping><description><![CDATA[<div></div><fieldset><legend><span style="color: #ff0000;">2016-07-08 日更新&nbsp;</span></legend><div><span style="color:red;">此篇博客已经迁移到新博客，并做行文检查和优化排版：</span></div><p>&nbsp;</p><a href="http://blog.clawz.me/2013/04/25/13-x-cpp-server/"><p><span style="color:red;">http://blog.clawz.me/2013/04/25/13-x-cpp-server/&nbsp;</span></p></a></fieldset><a href="http://blog.clawz.me/2013/04/25/13-x-cpp-server/"><p>&nbsp;</p><p>&nbsp;</p></a><p>一、简介</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;这个项目刚起步，将来有可能会演变为公司的服务器框架。博客里暂且称呼为X项目。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;语言为c++，之后将此服务器的设计演变尽量记录下来，为一个系列，以&#8220;X项目C++服务器&#8221;为统一标题开头。</p> <p>&nbsp;</p> <p>二、架构设计</p> <p>（一）多进程通信方案</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;zeromq</p> <p>（二）协议方案</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;protobuf&nbsp;</p> <p>（三）存储</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;redis</p> <p>（四）脚本</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;luaplus</p> <p>（五）日志</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;glog</p> <p>&nbsp;</p> <p>三、自动构建部署</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;自动构建等为敏捷开发提供保障。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;之前经历的那些项目（其中包括业内比较有名的2个大型项目）在自动构建部署方面基本为0，开发效率不高，这次新项目准备从一开始就做这方面的准备。</p> <p>（一）单测</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;单测框架考虑google的gtest。</p><p>&nbsp;</p><img src ="http://www.cppblog.com/yangsf5/aggbug/199704.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yangsf5/" target="_blank">Sheppard Y</a> 2013-04-25 14:52 <a href="http://www.cppblog.com/yangsf5/archive/2013/04/25/199704.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>cmake用cotire设置gcc的预编译头</title><link>http://www.cppblog.com/yangsf5/archive/2013/04/23/199658.html</link><dc:creator>Sheppard Y</dc:creator><author>Sheppard Y</author><pubDate>Tue, 23 Apr 2013 06:10:00 GMT</pubDate><guid>http://www.cppblog.com/yangsf5/archive/2013/04/23/199658.html</guid><wfw:comment>http://www.cppblog.com/yangsf5/comments/199658.html</wfw:comment><comments>http://www.cppblog.com/yangsf5/archive/2013/04/23/199658.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yangsf5/comments/commentRss/199658.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yangsf5/services/trackbacks/199658.html</trackback:ping><description><![CDATA[<div></div><fieldset><legend><span style="color: #ff0000;">2016-07-08 日更新&nbsp;</span></legend><div><span style="color:red;">此篇博客已经迁移到新博客，并做行文检查和优化排版：</span></div><div></div><a href="http://blog.clawz.me/2013/04/23/13-cmake-gcc-precompile/"><div><span style="color:red;">http://blog.clawz.me/2013/04/23/13-cmake-gcc-precompile/</span></div></a></fieldset><a href="http://blog.clawz.me/2013/04/23/13-cmake-gcc-precompile/"><div></div><p>&nbsp;</p></a><p><br /><br />一、预编译头</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;当工程大了，单机编译速度会很慢。预编译头会提高很大的速度。相关原理这里不赘述，网上很多。（或者老夫有空的时候再补充）</p> <p>&#8203;</p> <p>二、cmake设置gcc的预编译头</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;一开始google到一个国内同行写的cmake宏，用了下，貌似不是很好用。另外作者也表示还是有bug。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;后来找到cotire。目前使用良好。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;</p> <p>三、cotire（compile time reducer）</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;项目地址<a href="https://github.com/sakra/cotire" data_ue_src="https://github.com/sakra/cotire">https://github.com/sakra/cotire</a>。具体使用方式github里对应项目主页已经写的很清楚了（主页man看不明白的可以去看他的src里那个例子），这里只做下快捷备忘。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;步骤：</p> <p>1. clone这个git。</p> <p>2. 将cotire里的CMake/cotire.cmake拷到咱们自己工程的顶层CMakeLists.txt同级目录下。</p> <p>3. 往这个顶层CMakeLists.txt里设置一个变量并include：</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;(CMAKE_MODULE_PATH&nbsp;"${CMAKE_SOURCE_DIR}/CMake")</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;include(cotire)</p> <p>4. 在具体的CMakeLists.txt的add_executable后边再cotire下，如：</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&#8203;add_executable(MyExecutable&nbsp;${MyExecutableSources})<br />&nbsp;&nbsp;&nbsp;&nbsp;&#8203;target_link_libraries(MyExecutable&nbsp;${MyExecutableLibraries})<br />&nbsp;&nbsp;&nbsp;&nbsp;&#8203;cotire(MyExecutable)</p> <p>5. 上边是自动寻找预编译头，也可以自己设置，例如我们从vc跨平台过来的项目，显示设置stdafx.h，只用在cotire前边设置下即可：</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&#8203;set_target_properties(MyExecutable&nbsp;PROPERTIES&nbsp;COTIRE_CXX_PREFIX_HEADER_INIT&nbsp;"stdafx.h")<br />&nbsp;&nbsp;&nbsp;&nbsp;&#8203;&#8203;cotire(MyExecutable)</p><img src ="http://www.cppblog.com/yangsf5/aggbug/199658.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yangsf5/" target="_blank">Sheppard Y</a> 2013-04-23 14:10 <a href="http://www.cppblog.com/yangsf5/archive/2013/04/23/199658.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>尽管TCP客户端设置TCP_NODELAY,服务器仍须读到EAGAIN</title><link>http://www.cppblog.com/yangsf5/archive/2009/04/30/81545.html</link><dc:creator>Sheppard Y</dc:creator><author>Sheppard Y</author><pubDate>Thu, 30 Apr 2009 03:30:00 GMT</pubDate><guid>http://www.cppblog.com/yangsf5/archive/2009/04/30/81545.html</guid><wfw:comment>http://www.cppblog.com/yangsf5/comments/81545.html</wfw:comment><comments>http://www.cppblog.com/yangsf5/archive/2009/04/30/81545.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yangsf5/comments/commentRss/81545.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yangsf5/services/trackbacks/81545.html</trackback:ping><description><![CDATA[<div></div><fieldset><legend><span style="color: #ff0000;">2016-07-03 日更新&nbsp;</span></legend><div><span style="color:red;">此篇博客已经迁移到新博客，并做行文检查和优化排版：</span></div><div></div><a href="http://blog.clawz.me/2009/04/30/09-tcp-nodelay-also-eagain/"><div><span style="color:red;">http://blog.clawz.me/2009/04/30/09-tcp-nodelay-also-eagain/</span></div></a></fieldset><a href="http://blog.clawz.me/2009/04/30/09-tcp-nodelay-also-eagain/"><div></div></a><br />尽管TCP客户端设置TCP_NODELAY,服务器仍须读到EAGAIN才算完成一个EPOLLIN事件。<br /><br />一开始以为客户端设置了TCP_NODELAY选项就表示每一次发包都会触发新事件，<br />测试结果不是这样的。<br />很容易理解，TCP_NODELAY只是不让底层拼包，但是服务器端实际放到缓冲区的数据，还是来了就放缓冲区，<br />而EPOLL只管应用层。<img src ="http://www.cppblog.com/yangsf5/aggbug/81545.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yangsf5/" target="_blank">Sheppard Y</a> 2009-04-30 11:30 <a href="http://www.cppblog.com/yangsf5/archive/2009/04/30/81545.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>epoll的各个事件触发条件测试</title><link>http://www.cppblog.com/yangsf5/archive/2009/03/12/76353.html</link><dc:creator>Sheppard Y</dc:creator><author>Sheppard Y</author><pubDate>Thu, 12 Mar 2009 09:17:00 GMT</pubDate><guid>http://www.cppblog.com/yangsf5/archive/2009/03/12/76353.html</guid><wfw:comment>http://www.cppblog.com/yangsf5/comments/76353.html</wfw:comment><comments>http://www.cppblog.com/yangsf5/archive/2009/03/12/76353.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yangsf5/comments/commentRss/76353.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yangsf5/services/trackbacks/76353.html</trackback:ping><description><![CDATA[<div></div><fieldset><legend><span style="color: #ff0000;">2016-07-03 日更新&nbsp;</span></legend><div><span style="color:red;">此篇博客已经迁移到新博客，并做行文检查和优化排版：</span><br /><div></div><div><a href="http://blog.clawz.me/2009/03/12/09-epoll-event-test/"><span style="color:red;">http://blog.clawz.me/2009/03/12/09-epoll-event-test/</span></a></div></div></fieldset><div><div><a href="http://blog.clawz.me/2009/03/12/09-epoll-event-test/"></a></div></div><br />1、listen fd，有新连接请求，触发EPOLLIN。<br />2、对端发送普通数据，触发EPOLLIN。<br />3、带外数据，只触发EPOLLPRI。<br />4、对端正常关闭（程序里close()，shell下kill或ctr+c），触发EPOLLIN和EPOLLRDHUP，但是不触发EPOLLERR和EPOLLHUP。<br />&nbsp;&nbsp;&nbsp; 关于这点，以前一直以为会触发EPOLLERR或者EPOLLHUP<img height="20" src="http://www.cppblog.com/Emoticons/QQ/13.gif" width="20" border="0" alt="" />。<br />&nbsp;&nbsp;&nbsp; 再man epoll_ctl看下后两个事件的说明，这两个应该是本端（server端）出错才触发的。<br />5、对端异常断开连接（只测了拔网线），没触发任何事件。<br /><br /><br /><br /><br />附man：<br /><br />EPOLLIN<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The associated file is available for read(2) operations.<br />EPOLLOUT<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The associated file is available for write(2) operations.<br />EPOLLRDHUP<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Stream&nbsp; socket peer closed connection, or shut down writing half<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; of connection.&nbsp; (This flag is especially useful for writing sim-<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ple code to detect peer shutdown when using Edge Triggered moni-<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; toring.)<br />EPOLLPRI<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; There is urgent data available for read(2) operations.<br />EPOLLERR<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Error condition happened&nbsp; on&nbsp; the&nbsp; associated&nbsp; file&nbsp; descriptor.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; epoll_wait(2)&nbsp; will always wait for this event; it is not neces-<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sary to set it in events.<br />EPOLLHUP<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hang&nbsp; up&nbsp;&nbsp; happened&nbsp;&nbsp; on&nbsp;&nbsp; the&nbsp;&nbsp; associated&nbsp;&nbsp; file&nbsp;&nbsp; descriptor.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; epoll_wait(2)&nbsp; will always wait for this event; it is not neces-<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sary to set it in events.<br />EPOLLET<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sets&nbsp; the&nbsp; Edge&nbsp; Triggered&nbsp; behavior&nbsp; for&nbsp; the&nbsp; associated&nbsp; file<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; descriptor.&nbsp;&nbsp; The default behavior for epoll is Level Triggered.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; See epoll(7) for more detailed information about Edge and&nbsp; Level<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Triggered event distribution architectures.<br />EPOLLONESHOT (since Linux 2.6.2)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sets&nbsp; the&nbsp; one-shot behavior for the associated file descriptor.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; This means that after an event is pulled out with&nbsp; epoll_wait(2)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the&nbsp; associated&nbsp; file&nbsp; descriptor&nbsp; is internally disabled and no<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; other events will be reported by the epoll interface.&nbsp; The&nbsp; user<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; must&nbsp; call&nbsp; epoll_ctl() with EPOLL_CTL_MOD to re-enable the file<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; descriptor with a new event mask.<img src ="http://www.cppblog.com/yangsf5/aggbug/76353.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yangsf5/" target="_blank">Sheppard Y</a> 2009-03-12 17:17 <a href="http://www.cppblog.com/yangsf5/archive/2009/03/12/76353.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>变长结构体的技巧</title><link>http://www.cppblog.com/yangsf5/archive/2008/11/21/63564.html</link><dc:creator>Sheppard Y</dc:creator><author>Sheppard Y</author><pubDate>Fri, 21 Nov 2008 01:31:00 GMT</pubDate><guid>http://www.cppblog.com/yangsf5/archive/2008/11/21/63564.html</guid><wfw:comment>http://www.cppblog.com/yangsf5/comments/63564.html</wfw:comment><comments>http://www.cppblog.com/yangsf5/archive/2008/11/21/63564.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/yangsf5/comments/commentRss/63564.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yangsf5/services/trackbacks/63564.html</trackback:ping><description><![CDATA[<div><span style="color: red;"></span></div><fieldset><legend><span style="color: #ff0000;">2016-07-03 日更新</span></legend><div><span style="color:red;">此篇博客已经迁移到新博客，并做行文检查和优化排版：</span><br /><div></div></div><a href="http://blog.clawz.me/2008/11/21/08-bian-chang-jie-gou-ti/"><div><div><span style="color:red;">http://blog.clawz.me/2008/11/21/08-bian-chang-jie-gou-ti/</span></div></div></a></fieldset><a href="http://blog.clawz.me/2008/11/21/08-bian-chang-jie-gou-ti/"><div><div><span style="color: red;"></span></div></div><p>&nbsp;</p></a><p><br /><br /><br />本来C99支持变长数组了，但是我们项目组客户端的开发人员用的是vs2005，而MS的这个又不支持C99。没办法，我们服务器端得兼容他们。<br />所以变长结构体只能这样了：<br /></p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;_abc<br /><img id="Codehighlighter1_12_46_Open_Image" onclick="this.style.display='none'; Codehighlighter1_12_46_Open_Text.style.display='none'; Codehighlighter1_12_46_Closed_Image.style.display='inline'; Codehighlighter1_12_46_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img id="Codehighlighter1_12_46_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_12_46_Closed_Text.style.display='none'; Codehighlighter1_12_46_Open_Image.style.display='inline'; Codehighlighter1_12_46_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align="top"></span><span id="Codehighlighter1_12_46_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_12_46_Open_Text"><span style="color: #000000">{<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;count;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;str[</span><span style="color: #000000">0</span><span style="color: #000000">];<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000">;</span></div>
<p>&nbsp;</p>
<p>&nbsp;count记录str数组的大小。不一定是char类型，可以用宏来传递相应参数类型。<br />注意的地方：在申请空间时要根据count的值来多申请str的空间。</p><img src ="http://www.cppblog.com/yangsf5/aggbug/63564.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yangsf5/" target="_blank">Sheppard Y</a> 2008-11-21 09:31 <a href="http://www.cppblog.com/yangsf5/archive/2008/11/21/63564.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>