﻿<?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++博客-Just enjoy programming-随笔分类-linux</title><link>http://www.cppblog.com/tankzhouqiang/category/16135.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 08 Jan 2013 15:02:30 GMT</lastBuildDate><pubDate>Tue, 08 Jan 2013 15:02:30 GMT</pubDate><ttl>60</ttl><item><title>【操作系统】Linux性能监控——CPU、Memory、IO、Network（转载）</title><link>http://www.cppblog.com/tankzhouqiang/archive/2012/12/26/196699.html</link><dc:creator>周强</dc:creator><author>周强</author><pubDate>Wed, 26 Dec 2012 14:02:00 GMT</pubDate><guid>http://www.cppblog.com/tankzhouqiang/archive/2012/12/26/196699.html</guid><wfw:comment>http://www.cppblog.com/tankzhouqiang/comments/196699.html</wfw:comment><comments>http://www.cppblog.com/tankzhouqiang/archive/2012/12/26/196699.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tankzhouqiang/comments/commentRss/196699.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tankzhouqiang/services/trackbacks/196699.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 【操作系统】Linux性能监控&#8212;&#8212;CPU、Memory、IO、Networkby illidan（综合了几篇文章和自己的实践）&nbsp;一、CPU1、良好状态指标CPU利用率：User Time &lt;= 70%，System Time &lt;= 35%，User Time + System Time &lt;= 70%。上下文切换：与CPU利用率相关联，如果CPU利...&nbsp;&nbsp;<a href='http://www.cppblog.com/tankzhouqiang/archive/2012/12/26/196699.html'>阅读全文</a><img src ="http://www.cppblog.com/tankzhouqiang/aggbug/196699.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tankzhouqiang/" target="_blank">周强</a> 2012-12-26 22:02 <a href="http://www.cppblog.com/tankzhouqiang/archive/2012/12/26/196699.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>top命令(转载)</title><link>http://www.cppblog.com/tankzhouqiang/archive/2012/08/28/188551.html</link><dc:creator>周强</dc:creator><author>周强</author><pubDate>Tue, 28 Aug 2012 12:42:00 GMT</pubDate><guid>http://www.cppblog.com/tankzhouqiang/archive/2012/08/28/188551.html</guid><wfw:comment>http://www.cppblog.com/tankzhouqiang/comments/188551.html</wfw:comment><comments>http://www.cppblog.com/tankzhouqiang/archive/2012/08/28/188551.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tankzhouqiang/comments/commentRss/188551.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tankzhouqiang/services/trackbacks/188551.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: TOP是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执行该命令,它将独占前台,直到用户终止该程序为止.比较准确的说,top命令提供了实时的对系统处理器的状态监视.它将显示系统中CPU最&#8220;敏感&#8221;的任务列表.该命令可以按CPU使用.内存使用和执行时间对任务进行排序；而且该命令的很多特性都可以通过交互式命令或者在个人定制文件中进行设定.top - 12:38...&nbsp;&nbsp;<a href='http://www.cppblog.com/tankzhouqiang/archive/2012/08/28/188551.html'>阅读全文</a><img src ="http://www.cppblog.com/tankzhouqiang/aggbug/188551.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tankzhouqiang/" target="_blank">周强</a> 2012-08-28 20:42 <a href="http://www.cppblog.com/tankzhouqiang/archive/2012/08/28/188551.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>技巧：多共享动态库中同名对象重复析构问题的解决方法(转载)</title><link>http://www.cppblog.com/tankzhouqiang/archive/2012/03/02/166985.html</link><dc:creator>周强</dc:creator><author>周强</author><pubDate>Fri, 02 Mar 2012 08:04:00 GMT</pubDate><guid>http://www.cppblog.com/tankzhouqiang/archive/2012/03/02/166985.html</guid><wfw:comment>http://www.cppblog.com/tankzhouqiang/comments/166985.html</wfw:comment><comments>http://www.cppblog.com/tankzhouqiang/archive/2012/03/02/166985.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tankzhouqiang/comments/commentRss/166985.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tankzhouqiang/services/trackbacks/166985.html</trackback:ping><description><![CDATA[<p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">Linux 支持的共享程序库（<strong>lib*.so</strong>）技术不仅能够有效利用系统资源，而且还对程序设计带来了很大的便利性、通用性等，因此被各种级别的应用系统广泛采用。 动态链接的共享库是在加载应用程序时被加载的，而且它与应用程序是在运行时绑定的：通过动态链接器，将动态共享库映射进应用程序的可执行内存中（动态链接）；在启动应用程序时，动态装载器将所需的共享目标库映射到应用程序的内存（动态装载）。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">在通常情况下，共享库都是通过使用附加选项&nbsp;<strong>-fpic</strong>&nbsp;或&nbsp;<strong>-fPIC</strong>&nbsp;进行编译，从目标代码产生位置无关的代码（<strong>Position Independent Code，PIC</strong>），使用&nbsp;<strong>-shared</strong>选项将目标代码放进共享目标库中。位置无关代码需要能够被加载到不同进程的不同地址，并且能得以正确的执行，故其代码要经过特别的编译处理：位置无关代码（<strong>PIC</strong>）对常量和函数入口地址的操作都是采用基于基寄存器（base register）BASE+ 偏移量的相对地址的寻址方式。即使程序被装载到内存中的不同地址，即 BASE 值不同，而偏移量是不变的，所以程序仍然可以找到正确的入口地址或者常量。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">然而，当应用程序链接了多个共享库，如果在这些共享库中，存在相同作用域范围的同名静态成员变量或者同名 ( 非静态 ) 全局变量，那么当程序访问完静态成员变量或全局变量结束析构时，由于某内存块的 double free 会导致 core dump，这是由于 Linux 编译器的缺陷造成的。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; "><a name="major1"><span style="font-size: 1.5em; font-weight: bold; ">应用场景原型</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">该问题源于笔者所从事的开发项目：<strong>IBM Tivoli Workload Scheduler (TWS) LoadLeveler</strong>。<strong>LoadLeveler</strong>是&nbsp;<strong>IBM</strong>在高性能计算（<strong>High Performance Computing，HPC</strong>）领域的一款作业调度软件。它主要分为两个大的模块，分别是调度模块（scheduler）和资源管理模块（resource manger）。 两个模块中分别含有关于配置管理功能的共享库，由于某些配置管理选项为两模块所共同采用，所以两模块之间共享了部分源文件代码，其中包含有同名的类静态成员。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">可以通过以下简单的模型进行描述：</p><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><a name="fig1" style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; "><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">图 1. 应用场景</strong></a><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><img alt="图片示例" height="210" src="http://www.ibm.com/developerworks/cn/linux/l-cn-sdlstatic/figure1.gif" width="338" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " />&nbsp;<br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">对应的各模块代码片段如下图所示：</p><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><a name="fig2" style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; "><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">图 2. 应用场景模拟代码</strong></a><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><img alt="图片示例" height="606" src="http://www.ibm.com/developerworks/cn/linux/l-cn-sdlstatic/figure2.gif" width="494" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " />&nbsp;<br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">其中，test.c 是主程序，包含有两个头文件：api1.h 与 api2.h；头文件 api1.h 包含头文件 lib1/lib.h 和一功能函数 func_api1()，api2.h 包含头文件 lib2/lib.h 和一功能函数 func_api2()；目录 lib1 和 lib2 下的源文件分别编译生成共享库 lib1.so 和 lib2.so。同时，头文件 lib1/lib.h 与 lib2/lib.h 链接到同一共享文件 lib.h。在文件 lib.h 中定义有一静态成员变量&#8220;<strong>static std::vector&lt;int&gt; vec_int</strong>&#8221;。</p><div style="clear: both; background-image: url(http://1.www.s81c.com/i/solid.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #ffffff; height: 1px; font-family: Simsun; line-height: normal; text-align: left; font-size: medium; background-repeat: repeat no-repeat; "></div><p ibm-back-to-top"="" style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; font-size: 0.76em; clear: both; text-align: right; height: 15px; line-height: normal; background-color: #ffffff; "><a href="http://www.ibm.com/developerworks/cn/linux/l-cn-sdlstatic/#ibm-pcon" style="color: #996699; display: inline; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; text-decoration: none; background-image: url(http://1.www.s81c.com/i/v16/icons/u_bold.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; font-weight: bold; background-position: 0px -1px; background-repeat: no-repeat no-repeat; ">回页首</a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; "><a name="major2"><span style="font-size: 1.5em; font-weight: bold; ">功能函数与各静态成员函数代码清单</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">功能函数 func_api1() 与 func_api2() 的实现类似，通过调用静态成员函数达到访问静态成员变量&nbsp;<strong>vec_int</strong>的目的：</p><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><a name="listing1" style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; "><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 1. 功能函数 func_api1(int)</strong></a><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><table width="100%" cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; color: #000000; font-family: Simsun; text-align: left; background-color: #ffffff; "><tbody><tr><td style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; "><pre style="width: 694px; margin-top: 0px; margin-bottom: 0px; font-family: 'Andale Mono', 'Lucida Console', Monaco, Liberation, fixed, monospace; font-size: 11px; overflow-x: auto; overflow-y: auto; background-image: initial !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; ">          void func_api1(int i) {      printf("%s.\n", __FILE__);       A::set(i);      A::print();      return;   }      </pre></td></tr></tbody></table><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">静态成员函数 A::set() 与 A::print() 的实现如下：</p><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><a name="listing2" style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; "><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 2. 静态成员函数 A::set(int)</strong></a><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><table width="100%" cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; color: #000000; font-family: Simsun; text-align: left; background-color: #ffffff; "><tbody><tr><td style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; "><pre style="width: 694px; margin-top: 0px; margin-bottom: 0px; font-family: 'Andale Mono', 'Lucida Console', Monaco, Liberation, fixed, monospace; font-size: 11px; overflow-x: auto; overflow-y: auto; background-image: initial !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; ">          void A::set(int num) {      vec_int.clear();      for (int i = 0; i &lt; num; i++) {          vec_int.push_back(i);      }      return;   }      </pre></td></tr></tbody></table><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><a name="listing3" style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; "><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 3. 静态成员函数 A::print()</strong></a><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><table width="100%" cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; color: #000000; font-family: Simsun; text-align: left; background-color: #ffffff; "><tbody><tr><td style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; "><pre style="width: 694px; margin-top: 0px; margin-bottom: 0px; font-family: 'Andale Mono', 'Lucida Console', Monaco, Liberation, fixed, monospace; font-size: 11px; overflow-x: auto; overflow-y: auto; background-image: initial !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; ">          void A::print() {      for (int i = 0; i &lt; vec_int.size(); i++) {          printf("vec_int[%d] = %d, addr: %p.\n", i, vec_int[i], &amp;vec_int[i]);      }      printf("vec_int addr: %p.\n", &amp;vec_int);      return;   }      </pre></td></tr></tbody></table><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">A::set() 对静态成员&nbsp;<strong>vec_int</strong>进行赋值操作，而 A::print() 则打印其中的值与当前项的内存地址。</p><div style="clear: both; background-image: url(http://1.www.s81c.com/i/solid.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #ffffff; height: 1px; font-family: Simsun; line-height: normal; text-align: left; font-size: medium; background-repeat: repeat no-repeat; "></div><p ibm-back-to-top"="" style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; font-size: 0.76em; clear: both; text-align: right; height: 15px; line-height: normal; background-color: #ffffff; "><a href="http://www.ibm.com/developerworks/cn/linux/l-cn-sdlstatic/#ibm-pcon" style="color: #996699; display: inline; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; text-decoration: none; background-image: url(http://1.www.s81c.com/i/v16/icons/u_bold.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; font-weight: bold; background-position: 0px -1px; background-repeat: no-repeat no-repeat; ">回页首</a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; "><a name="major3"><span style="font-size: 1.5em; font-weight: bold; ">运行结果</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">如果两个共享库是通过选项&nbsp;<strong>-fpic</strong>或&nbsp;<strong>-fPIC</strong>编译的话，运行程序 test，输出如下：</p><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><a name="listing4" style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; "><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 4. 选项 -fPIC 的测试结果</strong></a><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><table width="100%" cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; color: #000000; font-family: Simsun; text-align: left; background-color: #ffffff; "><tbody><tr><td style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; "><pre style="width: 694px; margin-top: 0px; margin-bottom: 0px; font-family: 'Andale Mono', 'Lucida Console', Monaco, Liberation, fixed, monospace; font-size: 11px; overflow-x: auto; overflow-y: auto; background-image: initial !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; ">          $ export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH   $ g++ -g -o lib1.so <strong>-fPIC</strong>-rdynamic -shared lib1/lib.c   $ g++ -g -o lib2.so <strong>-fPIC</strong>-rdynamic -shared lib2/lib.c   $ g++ -g -o test -L./ -l1 -l2 test.c   $ <strong>./test</strong>  api1.h.   vec_int[0] = 0, addr: <strong>0x9cbf028</strong>.   vec_int[1] = 1, addr: 0x9cbf02c.   vec_int[2] = 2, addr: 0x9cbf030.   vec_int[3] = 3, addr: 0x9cbf034.   vec_int addr: <strong>0xe89228</strong>.   *** glibc detected *** ./test: double free or corruption (fasttop): <strong>0x09cbf028</strong>***   ======= <strong>Backtrace:</strong>=========   /lib/libc.so.6[0x2b2b16]   /lib/libc.so.6(cfree+0x90)[0x2b6030]   /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0x5d1731]   <strong>./lib1.so(_ZN9__gnu_cxx13new_allocatorIiE10deallocateEPij+0x1d)[0xe88417]</strong>         <strong>./lib1.so(_ZNSt12_Vector_baseIiSaIiEE13_M_deallocateEPij+0x33)[0xe88451]</strong>         <strong>./lib1.so(_ZNSt12_Vector_baseIiSaIiEED2Ev+0x42)[0xe8849a]</strong>         <strong>./lib1.so(_ZNSt6vectorIiSaIiEED1Ev+0x60)[0xe8850c]</strong>  ./lib2.so[0x961d6c]   /lib/libc.so.6(__cxa_finalize+0xa9)[0x275c79]   ./lib2.so[0x961c34]   ./lib2.so[0x962d3c]   /lib/ld-linux.so.2[0x23a7de]   /lib/libc.so.6(exit+0xe9)[0x2759c9]   /lib/libc.so.6(__libc_start_main+0xe4)[0x25fdf4]   ./test(__gxx_personality_v0+0x45)[0x80484c1]   ======= <strong>Memory map:</strong>========   ......   00960000-00963000 r-xp 00000000 00:1b 7668734    ./lib2.so   00963000-00964000 rwxp 00003000 00:1b 7668734    ./lib2.so   00970000-00971000 r-xp 00970000 00:00 0          [vdso]   00e86000-00e89000 r-xp 00000000 00:1b 7668022    ./lib1.so   <strong>00e89000-00e8a000 rwxp 00003000 00:1b 7668022    ./lib1.so</strong>  08048000-08049000 r-xp 00000000 00:1b 7668748    ./test   08049000-0804a000 rw-p 00000000 00:1b 7668748    ./test   <strong>09cbf000-09ce0000 rw-p 09cbf000 00:00 0          [heap]</strong>  ......   Abort(coredump)   $      </pre></td></tr></tbody></table><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">从程序的输出直观的看到，core 产生是由于堆内存区域（<strong>09cbf000-09ce0000</strong>）中起始地址为&nbsp;<strong>0x09cbf028</strong>的内存区被释放了两次导致的，该地址正式静态成员变量&nbsp;<strong>vec_int</strong>的第一个元素的地址。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">为什么会出现同一块内存区，被释放两次的情形呢？</p><div style="clear: both; background-image: url(http://1.www.s81c.com/i/solid.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #ffffff; height: 1px; font-family: Simsun; line-height: normal; text-align: left; font-size: medium; background-repeat: repeat no-repeat; "></div><p ibm-back-to-top"="" style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; font-size: 0.76em; clear: both; text-align: right; height: 15px; line-height: normal; background-color: #ffffff; "><a href="http://www.ibm.com/developerworks/cn/linux/l-cn-sdlstatic/#ibm-pcon" style="color: #996699; display: inline; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; text-decoration: none; background-image: url(http://1.www.s81c.com/i/v16/icons/u_bold.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; font-weight: bold; background-position: 0px -1px; background-repeat: no-repeat no-repeat; ">回页首</a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; "><a name="major4"><span style="font-size: 1.5em; font-weight: bold; ">原因分析</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">我们知道，静态成员变量与全局变量类似，都采用了静态存储方式。对于加了选项&nbsp;<strong>-fpic</strong>或&nbsp;<strong>-fPIC</strong>的共享库，这些变量的地址都存放在该共享库的全局偏移表（<strong>Global Offset Table，GOT</strong>）中。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">通过&nbsp;<strong>objdump</strong>或者&nbsp;<strong>readelf</strong>命令分析共享库&nbsp;<strong>lib1.so</strong>，结果如下：</p><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><a name="listing5" style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; "><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 5. objdump 分析共享库 lib1.so 的输出</strong></a><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><table width="100%" cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; color: #000000; font-family: Simsun; text-align: left; background-color: #ffffff; "><tbody><tr><td style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; "><pre style="width: 694px; margin-top: 0px; margin-bottom: 0px; font-family: 'Andale Mono', 'Lucida Console', Monaco, Liberation, fixed, monospace; font-size: 11px; overflow-x: auto; overflow-y: auto; background-image: initial !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; ">          $ objdump -x -R lib1.so    lib1.so:     file format elf32-i386   ......   Sections:   Idx Name          Size      VMA       LMA       File off  Algn    0 .gnu.hash     000001e8  000000d4  000000d4  000000d4  2**2                    CONTENTS, ALLOC, LOAD, READONLY, DATA   ......   18 .dynamic      000000d8  0000301c  0000301c  0000301c  2**2                    CONTENTS, ALLOC, LOAD, DATA   <strong>19 .got          00000014  000030f4  000030f4  000030f4  2**2</strong>                   CONTENTS, ALLOC, LOAD, DATA   20 .got.plt      00000114  00003108  00003108  00003108  2**2                    CONTENTS, ALLOC, LOAD, DATA   ......   DYNAMIC RELOCATION RECORDS   OFFSET   TYPE              VALUE   ......   000030f4 R_386_GLOB_DAT    __gmon_start__   000030f8 R_386_GLOB_DAT    _Jv_RegisterClasses   <strong>000030fc R_386_GLOB_DAT    _ZN1A7vec_intE</strong>  00003104 R_386_GLOB_DAT    __cxa_finalize   ......      </pre></td></tr></tbody></table><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><a name="listing6" style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; "><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 6. readelf 分析共享库 lib1.so 的输出</strong></a><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><table width="100%" cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; color: #000000; font-family: Simsun; text-align: left; background-color: #ffffff; "><tbody><tr><td style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; "><pre style="width: 694px; margin-top: 0px; margin-bottom: 0px; font-family: 'Andale Mono', 'Lucida Console', Monaco, Liberation, fixed, monospace; font-size: 11px; overflow-x: auto; overflow-y: auto; background-image: initial !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; ">          $ objdump -x -R lib1.so    lib1.so:     file format elf32-i386   ......   Sections:   Idx Name          Size      VMA       LMA       File off  Algn    0 .gnu.hash     000001e8  000000d4  000000d4  000000d4  2**2                    CONTENTS, ALLOC, LOAD, READONLY, DATA   ......   18 .dynamic      000000d8  0000301c  0000301c  0000301c  2**2                    CONTENTS, ALLOC, LOAD, DATA   <strong>19 .got          00000014  000030f4  000030f4  000030f4  2**2</strong>                   CONTENTS, ALLOC, LOAD, DATA   20 .got.plt      00000114  00003108  00003108  00003108  2**2                    CONTENTS, ALLOC, LOAD, DATA   ......   DYNAMIC RELOCATION RECORDS   OFFSET   TYPE              VALUE   ......   000030f4 R_386_GLOB_DAT    __gmon_start__   000030f8 R_386_GLOB_DAT    _Jv_RegisterClasses   <strong>000030fc R_386_GLOB_DAT    _ZN1A7vec_intE</strong>  00003104 R_386_GLOB_DAT    __cxa_finalize   ......      </pre></td></tr></tbody></table><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">从上面两个命令的输出结果中可以看出，共享库&nbsp;<strong>lib1.so</strong>中&nbsp;<strong>GOT</strong>段的起始内存地址为&nbsp;<strong>000030f4</strong>，大小为 20 字节 (0x14)；静态成员变量&nbsp;<strong>vec_int</strong>在共享库&nbsp;<strong>lib1.so</strong>中的起始偏移地址为&nbsp;<strong>000030fc</strong>。显然，<strong>vec_int</strong>位于该共享库的&nbsp;<strong>GOT</strong>段内。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">当应用程序同时链接&nbsp;<strong>lib1.so</strong>和&nbsp;<strong>lib2.so</strong>时，同名静态成员变量&nbsp;<strong>vec_int</strong>分别位于其共享库的&nbsp;<strong>GOT</strong>区。当程序运行时，系统从符号表中查找并装载构造一份&nbsp;<strong>vec_int</strong>数据，这点从程序运行的输出结果（清单 4）的&#8220;<strong>Backtrace</strong>&#8221;部分可以看到：只有&nbsp;<strong>lib1.so</strong>中的静态成员变量被装载构造；同时，通过内存映射（<strong>Memory map</strong>）部分（清单 4），可以观察到&nbsp;<strong>vec_int</strong>对象的地址&nbsp;<strong>0xe89228</strong>正好处在为共享库&nbsp;<strong>lib1.so</strong>分配的可读内存区&nbsp;<strong>00e89000-00e8a000</strong>中：</p><table width="100%" cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; color: #000000; font-family: Simsun; text-align: left; background-color: #ffffff; "><tbody><tr><td style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; "><pre style="width: 694px; margin-top: 0px; margin-bottom: 0px; font-family: 'Andale Mono', 'Lucida Console', Monaco, Liberation, fixed, monospace; font-size: 11px; overflow-x: auto; overflow-y: auto; background-image: initial !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; ">        <strong>00e89000-00e8a000 rwxp 00003000 00:1b 7668022    ./lib1.so</strong></pre></td></tr></tbody></table><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">然后，当程序结束时，却对该变量进行了两次析构操作，通过&nbsp;<strong>gdb</strong>分析 core 文件：</p><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><a name="listing7" style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; "><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 7. core 文件分析结果</strong></a><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><table width="100%" cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; color: #000000; font-family: Simsun; text-align: left; background-color: #ffffff; "><tbody><tr><td style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; "><pre style="width: 694px; margin-top: 0px; margin-bottom: 0px; font-family: 'Andale Mono', 'Lucida Console', Monaco, Liberation, fixed, monospace; font-size: 11px; overflow-x: auto; overflow-y: auto; background-image: initial !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; ">          $ <strong>gdb ./test core.28440</strong> &#8230;&#8230;  Core was generated by `./test'.   Program terminated with signal 6, Aborted.   #0  0x00970402 in __kernel_vsyscall ()   (gdb)   (gdb) where   #0  0x00970402 in __kernel_vsyscall ()   #1  0x00272d10 in raise () from /lib/libc.so.6   #2  0x00274621 in abort () from /lib/libc.so.6   #3  0x002aae5b in __libc_message () from /lib/libc.so.6   #4  0x002b2b16 in _int_free () from /lib/libc.so.6   #5  0x002b6030 in free () from /lib/libc.so.6   #6  0x005d1731 in operator delete () from /usr/lib/libstdc++.so.6   #7  0x00e88417 in __gnu_cxx::new_allocator&lt;int&gt;::deallocate       (this=0xe89228, __p=0x9cbf028)      at /usr/lib/gcc/i386-redhat-linux/.../ext/new_allocator.h:94   #8  0x00e88451 in std::_Vector_base&lt;int, ... (this=0xe89228, __p=0x9cbf028, __n=4)      at /usr/lib/gcc/.../include/c++/4.1.2/bits/stl_vector.h:133   #9  0x00e8849a in ~_Vector_base (this=0xe89228)      at /usr/lib/gcc/.../include/c++/4.1.2/bits/stl_vector.h:119   #10 <strong>0x00e8850c</strong>in ~vector (this=0xe89228) at /usr/lib/gcc/.../stl_vector.h:272   #11 0x00961d6c in __tcf_0 () at lib2/lib.c:3   #12 0x00275c79 in __cxa_finalize () from /lib/libc.so.6   #13 0x00961c34 in __do_global_dtors_aux () from ./lib2.so   <strong>#14 0x00962d3c in _fini () from ./lib2.so</strong>  #15 0x0023a7de in _dl_fini () from /lib/ld-linux.so.2   #16 0x002759c9 in exit () from /lib/libc.so.6   #17 0x0025fdf4 in __libc_start_main () from /lib/libc.so.6   #18 0x080484c1 in _start ()   (gdb)      </pre></td></tr></tbody></table><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">从清单 7 中可以看出，从帧 #14 开始，程序进行&nbsp;<strong>lib2.so</strong>中的析构操作，直到 #11，都运行在&nbsp;<strong>lib2.so</strong>中，当进入帧 #10 时，进行变量析构时，其地址为&nbsp;<strong>0x00e8850c</strong>，该地址中的对象是程序启动时由共享库&nbsp;<strong>lib1.so</strong>装载构造出来的（清单 1）：</p><table width="100%" cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; color: #000000; font-family: Simsun; text-align: left; background-color: #ffffff; "><tbody><tr><td style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; "><pre style="width: 694px; margin-top: 0px; margin-bottom: 0px; font-family: 'Andale Mono', 'Lucida Console', Monaco, Liberation, fixed, monospace; font-size: 11px; overflow-x: auto; overflow-y: auto; background-image: initial !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; ">        <strong>./lib1.so(_ZNSt6vectorIiSaIiEED1Ev+0x60)[0xe8850c]</strong></pre></td></tr></tbody></table><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">当程序结束时，运行库&nbsp;<strong>glibc</strong>检测到共享库&nbsp;<strong>lib2.so</strong>析构了并非由其构造的对象，导致了 core dump。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">这种情况下，如果替换使用选项&nbsp;<strong>-fpie</strong>或&nbsp;<strong>-fPIE</strong>，操作步骤与运行结果如下所示：</p><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><a name="listing8" style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; "><strong style="font-size: 0.76em; font-weight: bold; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-family: arial, sans-serif; ">清单 8. 选项 -fPIE 的测试结果</strong></a><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><table width="100%" cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; color: #000000; font-family: Simsun; text-align: left; background-color: #ffffff; "><tbody><tr><td style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-top: 2px; padding-right: 2px; padding-bottom: 5px; padding-left: 2px; "><pre style="width: 694px; margin-top: 0px; margin-bottom: 0px; font-family: 'Andale Mono', 'Lucida Console', Monaco, Liberation, fixed, monospace; font-size: 11px; overflow-x: auto; overflow-y: auto; background-image: initial !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; ">          $ export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH   $ g++ -g -o lib1.so <strong>-fPIE</strong>-rdynamic -shared lib1/lib.c   $ g++ -g -o lib2.so <strong>-fPIE</strong>-rdynamic -shared lib2/lib.c   $ g++ -g -pie -o test -L./ -l1 -l2 test.c   $ <strong>./test</strong>  api1.h.   vec_int[0] = 0, addr: 0x80e3028.   vec_int[1] = 1, addr: 0x80e302c.   vec_int[2] = 2, addr: 0x80e3030.   vec_int[3] = 3, addr: 0x80e3034.   vec_int addr: 0x75e224.   $      </pre></td></tr></tbody></table><br style="font-family: Simsun; line-height: normal; text-align: left; background-color: #ffffff; font-size: medium; " /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">程序运行结果符合期望并正常结束。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">这是因为，当使用选项&nbsp;<strong>-fpie</strong>或&nbsp;<strong>-fPIE</strong>时，生成的共享库不会为静态成员变量或全局变量在&nbsp;<strong>GOT</strong>中创建对应的条目（通过&nbsp;<strong>objdump</strong>或<strong>readelf</strong>命令可以查看，此处不再赘述），从而避免了由于静态对象&#8220;构造一次，析构两次&#8221;而对同一内存区域释放两次引起的程序 core dump。</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">选项&nbsp;<strong>-fpie</strong>和&nbsp;<strong>-fPIE</strong>与&nbsp;<strong>-fpic</strong>及&nbsp;<strong>-fPIC</strong>的用法很相似，区别在于前者总是将生成的位置无关代码看作是属于程序本身，并直接链接进该可执行程序，而非存入全局偏移表&nbsp;<strong>GOT</strong>中；这样，对于同名的静态或全局对象的访问，其构造与析构操作将保持一一对应。</p><div style="clear: both; background-image: url(http://1.www.s81c.com/i/solid.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #ffffff; height: 1px; font-family: Simsun; line-height: normal; text-align: left; font-size: medium; background-repeat: repeat no-repeat; "></div><p ibm-back-to-top"="" style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; font-size: 0.76em; clear: both; text-align: right; height: 15px; line-height: normal; background-color: #ffffff; "><a href="http://www.ibm.com/developerworks/cn/linux/l-cn-sdlstatic/#ibm-pcon" style="color: #996699; display: inline; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; text-decoration: none; background-image: url(http://1.www.s81c.com/i/v16/icons/u_bold.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; font-weight: bold; background-position: 0px -1px; background-repeat: no-repeat no-repeat; ">回页首</a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; "><a name="major5"><span style="font-size: 1.5em; font-weight: bold; ">结束语</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; line-height: normal; text-align: left; background-color: #ffffff; ">通过使用选项&nbsp;<strong>-fpie</strong>或&nbsp;<strong>-fPIE</strong>代替&nbsp;<strong>-fpic</strong>或者&nbsp;<strong>-fPIC</strong>，使得生成的共享库不会为静态成员变量或全局变量在&nbsp;<strong>GOT</strong>中创建对应的条目，同时也就避免了针对同名静态对象&#8220;构造一次，析构两次&#8221;的不当操作。<br /><br />转自：<a href="http://www.ibm.com/developerworks/cn/linux/l-cn-sdlstatic/">http://www.ibm.com/developerworks/cn/linux/l-cn-sdlstatic/</a>&nbsp;<br /><br /><br /><br /><br /><br /></p><img src ="http://www.cppblog.com/tankzhouqiang/aggbug/166985.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tankzhouqiang/" target="_blank">周强</a> 2012-03-02 16:04 <a href="http://www.cppblog.com/tankzhouqiang/archive/2012/03/02/166985.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux RPC  测试（转载）</title><link>http://www.cppblog.com/tankzhouqiang/archive/2011/08/07/152718.html</link><dc:creator>周强</dc:creator><author>周强</author><pubDate>Sun, 07 Aug 2011 08:44:00 GMT</pubDate><guid>http://www.cppblog.com/tankzhouqiang/archive/2011/08/07/152718.html</guid><wfw:comment>http://www.cppblog.com/tankzhouqiang/comments/152718.html</wfw:comment><comments>http://www.cppblog.com/tankzhouqiang/archive/2011/08/07/152718.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tankzhouqiang/comments/commentRss/152718.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tankzhouqiang/services/trackbacks/152718.html</trackback:ping><description><![CDATA[<div>转自:<div>http://www.justwinit.cn/post/3960/</div><br /><br />RPC是glibc提供的函数参数/返回值封装服务, 并将封装结果通过网络传到服务器.<br />RPC服务端首先要启动portmapper服务.<br />测试一个简单的RPC传输示例, 先定义一个模板文件test.x<br /><br /><div>program TESTPROG{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;version VERSION{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int int_echo(int)=1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int get_str_len(string)=2;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int add ( int, int ) = 3;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}=1;<br />}=30000;</div>内含3个函数, 注意其中一个有2个参数.<br />然后可以用rpcgen生成一个Makefile:<br /><br /><div>rpcgen -a -N test.x</div><br />这会生成Makefile, 客户端和服务端的程序, 和函数示例.<br />我们手工修改一下Makefile<br /><br /><div># This is a template Makefile generated by rpcgen<br /># Parameters<br />CLIENT = test_client<br />SERVER = test_server<br />SOURCES_CLNT.c =<br />SOURCES_CLNT.h =<br />SOURCES_SVC.c =<br />SOURCES_SVC.h =<br />SOURCES.x = test.x<br />TARGETS_SVC.c = test_svc.c test_server.c test_xdr.c<br />TARGETS_CLNT.c = test_clnt.c test_client.c test_xdr.c<br />TARGETS = test.h test_xdr.c test_clnt.c test_svc.c<br />OBJECTS_CLNT = $(SOURCES_CLNT.c:%.c=%.o) $(TARGETS_CLNT.c:%.c=%.o)<br />OBJECTS_SVC = $(SOURCES_SVC.c:%.c=%.o) $(TARGETS_SVC.c:%.c=%.o)<br /># Compiler flags<br />CFLAGS += -g -pipe<br />LDLIBS += -lnsl<br />RPCGENFLAGS = -N<br /># Targets<br />all : $(CLIENT) $(SERVER)<br />$(TARGETS) : $(SOURCES.x)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rpcgen $(RPCGENFLAGS) $(SOURCES.x)<br />$(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) $(TARGETS_CLNT.c)<br />$(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) $(TARGETS_SVC.c)<br />$(CLIENT) : $(OBJECTS_CLNT)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) $(LDLIBS)<br />$(SERVER) : $(OBJECTS_SVC)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS)<br /> clean:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $(RM) core $(TARGETS) $(OBJECTS_CLNT) $(OBJECTS_SVC) $(CLIENT) $(SERVER)</div><br />修改test_server.c服务端的处理函数, 提供3种服务:<br /><br /><div>/*<br /> * This is sample code generated by rpcgen.<br /> * These are only templates and you can use them<br /> * as a guideline for developing your own functions.<br /> */<br />#include "test.h"<br />int *<br />int_echo_1_svc(int arg1,&nbsp;&nbsp;struct svc_req *rqstp)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static int&nbsp;&nbsp;result;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//echo.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result=arg1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("[RPC1] source=%d, echo=%d\n", arg1, result);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &amp;result;<br />}<br />int *<br />get_str_len_1_svc(char *arg1,&nbsp;&nbsp;struct svc_req *rqstp)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static int&nbsp;&nbsp;result;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//get strlen.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result=strlen(arg1);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("[PRC2] str=%s, len=%d\n", arg1, result);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &amp;result;<br />}<br />int *<br />add_1_svc(int arg1, int arg2,&nbsp;&nbsp;struct svc_req *rqstp)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static int&nbsp;&nbsp;result;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result=arg1+arg2;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("[RPC3] %d+%d=%d\n", arg1, arg2, result);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &amp;result;<br />}</div><br />客户端test_client.c, 调用这三种服务:<br /><br /><div>/*<br /> * This is sample code generated by rpcgen.<br /> * These are only templates and you can use them<br /> * as a guideline for developing your own functions.<br /> */<br />#include "test.h"<br />void<br />testprog_1(char *host)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLIENT *clnt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;*result_1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int int_echo_1_arg1=55;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;*result_2;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char *get_str_len_1_arg1="Hello, world";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;*result_3;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int add_1_arg1=10;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int add_1_arg2=20;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clnt = clnt_create (host, TESTPROG, VERSION, "udp");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (clnt == NULL) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clnt_pcreateerror (host);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit (1);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result_1 = int_echo_1(int_echo_1_arg1, clnt);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (result_1 == (int *) NULL) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clnt_perror (clnt, "call failed");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("[PRC1] echo %d, source %d\n", *result_1,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int_echo_1_arg1);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result_2 = get_str_len_1(get_str_len_1_arg1, clnt);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (result_2 == (int *) NULL) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clnt_perror (clnt, "call failed");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("[RPC2] return %d, should %d\n", *result_2,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strlen(get_str_len_1_arg1));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result_3 = add_1(add_1_arg1, add_1_arg2, clnt);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (result_3 == (int *) NULL) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clnt_perror (clnt, "call failed");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("[PRC3] %d+%d=%d\n", add_1_arg1, add_1_arg2,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*result_3);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clnt_destroy (clnt);<br />}</div>OK, 可以调用make了.<br />生成可执行程序test_server和test_client.<br />我们启动./test_server, 用rpcinfo看看:<br /><br /><div>$rpcinfo -p 127.0.0.1<br />program vers proto port<br />100000 2 tcp 111 portmapper<br />30000 1 udp 36307<br />30000 1 tcp 34883<br />Bingo! 启动成功.</div><br />再开个终端, 尝试一下调用.<br /><div><br />./test_client 127.0.0.1<br />[PRC1] echo 55, source 55<br />[RPC2] return 12, should 12<br />[PRC3] 10+20=30</div><br />正是我们期望的.<br /><br />Add By：Jackxiang<br /><div>make -f Makefile.test</div></div><img src ="http://www.cppblog.com/tankzhouqiang/aggbug/152718.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tankzhouqiang/" target="_blank">周强</a> 2011-08-07 16:44 <a href="http://www.cppblog.com/tankzhouqiang/archive/2011/08/07/152718.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux 进程间通信之消息传递</title><link>http://www.cppblog.com/tankzhouqiang/archive/2011/07/07/150362.html</link><dc:creator>周强</dc:creator><author>周强</author><pubDate>Wed, 06 Jul 2011 18:29:00 GMT</pubDate><guid>http://www.cppblog.com/tankzhouqiang/archive/2011/07/07/150362.html</guid><wfw:comment>http://www.cppblog.com/tankzhouqiang/comments/150362.html</wfw:comment><comments>http://www.cppblog.com/tankzhouqiang/archive/2011/07/07/150362.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/tankzhouqiang/comments/commentRss/150362.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tankzhouqiang/services/trackbacks/150362.html</trackback:ping><description><![CDATA[linux 进程间通信中消息传递主要分为管道，FIFO,消息队列<br />（1）管道<br />管道由pipe函数创建，提供一个单路（单向）数据流。pipe函数返回两个文件描述符：fd[0]和fd[1]。前者打开来读，后者打开来写。管道没有名字，所以只能由有亲缘关系的进程使用。尽管管道是由单个进程创建的，它却很少在单个进程内使用。管道的典型用途为两个不同进程（一个是父进程，一个是子进程）提供进程间的通信手段。首先，由一个进程（它将成为父进程）创建一个管道后调用fork派生一个自身的副本。接着，父进程关闭这个管道的读出端，子进程关闭同一管道的写入端。或者父进程关闭这个管道的写入端，子进程关闭同一管道的读出端。这就在父子进程间提供了一个单向数据流。<br /><br />（2）FIFO<br />FIFO指代先进先出（First in,First out),linux中的FIFO类似管道。它是一个单向（半双工）数据流。不同于管道的是，每个FIFO有一个路径名与之关联，从而允许无亲缘关系的进程访问同一个FIFO。FIFO也称为有名管道。FIFO由mkfifo函数创建。其中pathname是一个普通的Unix路径名，它是该FIFO的名字。mkfifo 函数已隐含指定 O_CREAT|O_EXCL. 也就是说，它那么创建一个新的FIFO，要么返回一个EEXIST错误（如果所指定的名字的FIFO已经存在）。如果不想希望创建一个新的FIFO,那就改为调用open而不是mkfifo.要打开一个已存在的FIFO或创建一个新的FIFO,应先调用mkfifo,再检查它是否返回EEXIST错误，若返回该错误则改为调用open.mkfifo　命令也能创建FIFO。可以从shell脚本或命令行中使用它。在创建出一个FIFO后，它必须或者打开来读，或者打开来写，所用的可以是open函数，也可以是某个标准I/O打开函数。FIFO不能打开来既读又写，因为它是半双工的。对管道或FIFO的write总是往末尾添加数据，对它们的read则总是从开头返回数据。如果对管道或FIFO调用lseek,那就返回ESPIPE错误。<br /><br />（３）Posix　消息队列<br />消息队列可认为是一个消息链表。有足够写权限的线程可往队列中放置消息，有足够读权限的线程可从队列中取走消息。每个消息都是一个记录，它由发送者赋予一个优先级。在某个进程往一个队列写入消息之前，并不需要另外某个进程在该队列上等待消息的到达。这跟管道和FIFO是相反的，对后者来说，除非读出者已存在，否则先有写入者是没有意义的。一个进程可以往某个队列写入一些消息，然后终止，再让另外一个进程在以后某个时刻读出这些消息。消息队列具有随内核的持续性，这跟管道和FIFO不一样。Posix消息队列和System V消息队列。这两组函数间存在许多相似性，但也有主要的区别<br />１. 对Posix消息队列的读总是返回最高优先级的最早消息，对System　Ｖ消息队列的读则可以返回任意指定优先级的消息。<br />２.当往一个空队列放置一个消息时，Posix　消息队列允许产生一个信号或启动一个线程。System　Ｖ消息队列则不提供类似机制。<br /><br />队列中的每个消息具有如下属性：<br />１.一个无符号整数优先级（Posix）或一个长整数类型(System V).<br />2.消息的数据部分长度（可以为０）.<br />3.数据本身（如果长度大于０）<br /><br />函数接口<br />１. mqd_t mq_open(const char *name,int oflag,...)<br />mq_open函数创建一个新的消息队列或打开一个已存在的消息队列<br />２.int mq_close(mqd_t mqdes);<br />mq_close函数关闭一个消息队列。<br />３.int mq_unlink(const char *name);<br />从系统中删除用作第一个参数的某个name.<br />4. int mq_getattr(mqd_t mqdes,struct mq_attr *attr);<br />&nbsp;&nbsp; int mq_setattr(mqd_t mqdes,const struct mq_attr *attr,struct mq_attr *oattr);<br />每个消息队列有四个属性，mq_getattr返回所有这些属性，mq_setattr则设置其中某个属性。<br />struct mq_attr{<br />&nbsp;&nbsp; long mq_flags;<br />&nbsp;&nbsp; long mq_maxmsg;<br />&nbsp;&nbsp; long mq_msgsize;<br />&nbsp;&nbsp; long mq_curmsgs;<br />};<br /><div>5.int mq_send(mqd_t mqdes,const char *ptr,size_t len,unsigned int prio);<br />　int mq_receive(mqd_t mqdes,char *ptr,size_t len,unsigned int *priop);<br /><div> mq_send函数往消息队列中写入消息，mq_receive函数从消息队列中读出消息。<br /><br />６.int mq_notify(mqd_t mqdes,const struct sigevent *motification);<br />结构体：<br />union sigval{<br />&nbsp;&nbsp;&nbsp; int sival_int;<br />&nbsp;&nbsp;&nbsp; void *sival_ptr;<br />};<br /><br />struct sigevent<br />{<br />&nbsp;&nbsp;&nbsp; int sigev_notify;<br />&nbsp;&nbsp;&nbsp; int sigev_signo;<br />&nbsp;&nbsp;&nbsp; union sigval sigev_value;<br />&nbsp;&nbsp;&nbsp; void&nbsp; (*sigev_notify_function)(union sigval);<br />&nbsp;&nbsp;&nbsp; pthread_attr_t *sigev_notify_attributes;<br />};<br /></div><div>mq_notify函数为指定队列建立或删除异步事件通知。一些普遍适用于该函数的若干规则<br />１).如果notification参数非空，那么当前进程希望在一个消息达到所指定的先前为空的队列时得到通知。我们说"该进程被注册为接收该队列的通知"。<br />２).如果notification参数为空指针，而且当前进程目前被注册为接收所指定队列的通知，那么已存在的注册将被撤销。<br />３）.任意时刻只有一个进程可以被注册为接收某个给定队列的通知。<br />４）.当有一个消息达到某个先前为空的队列，而且已有一个进程被注册为接收该队列的通知时，只有在没有任何线程阻塞在该队列的mq_receive调用中的前提下，通知才会发出。这就是说，在mq_receive调用中的阻塞比任何通知的注册都优先。<br />５）.当该通知被发送给它的注册进程时，其注册即被撤销。该进程必须再次调用mq_notify以重新注册（想要的话）。<br /><br />参考：Unix进程间通信</div><br /></div><img src ="http://www.cppblog.com/tankzhouqiang/aggbug/150362.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tankzhouqiang/" target="_blank">周强</a> 2011-07-07 02:29 <a href="http://www.cppblog.com/tankzhouqiang/archive/2011/07/07/150362.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux 进程间通信综述</title><link>http://www.cppblog.com/tankzhouqiang/archive/2011/07/04/150085.html</link><dc:creator>周强</dc:creator><author>周强</author><pubDate>Mon, 04 Jul 2011 01:58:00 GMT</pubDate><guid>http://www.cppblog.com/tankzhouqiang/archive/2011/07/04/150085.html</guid><wfw:comment>http://www.cppblog.com/tankzhouqiang/comments/150085.html</wfw:comment><comments>http://www.cppblog.com/tankzhouqiang/archive/2011/07/04/150085.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/tankzhouqiang/comments/commentRss/150085.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tankzhouqiang/services/trackbacks/150085.html</trackback:ping><description><![CDATA[linux进程间通信主要分为以下4个领域<br />（1）消息传递（管道，FIFO，消息队列）<br />（2）同步（互斥锁，条件变量，读写锁，信号量）<br />（3）共享内存区（匿名共享内存区，有名共享内存区）<br />（4）过程调用（Solaris门，Sun RPC）<br /><br /><br />linux进程间的信息共享可以分为<br />（1） 基于文件系统的共享<br />（2） 基于内核的共享<br />（3） 基于共享内存区的共享<br /><br /><br />IPC对象的持续性<br />（1）随进程间持续的IPC对象一直存在到打开着该对象的最后一个进程关闭该对象的最后一个进程关闭该对象为止。<br />（2）随内核持续的IPC对象一直存在到内核重新自举或显式删除该对象为止。<br />（3）随文件系统持续的IPC对象一直存在到显示删除该对象为止。即使系统自举了，该对象还是存在的。<br /><br /><br />IPC类型&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 持续性<br />管道&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 随进程<br />FIFO&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 随进程<br /><br />Posix互斥锁&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 随进程<br />Posix条件变量&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 随进程<br />Posix读写锁&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 随进程<br />fcntl记录上锁&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 随进程<br /><br />Posix消息队列&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 随内核<br />Posix有名信号量&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 随内核<br />Posix基于内存的信号量&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 随进程<br />Posix共享内存区&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 随内核<br /><br />System V消息队列&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 随内核<br />System V信号量&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 随内核<br />System V共享内存区&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 随内核<br /><br />TCP套接字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 随进程<br />UDP套接字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 随进程<br />Unix域套接字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 随进程<br /><br /><br /><br /><br /><div><br /> <br /> 名字空间：<br /> 当两个或多个无亲缘关系的进程使用某种类型的IPC对象来彼此交换信息时，该IPC对象必须有一个某种形式的名字或者标识符，这样其中一个进程（往往是服务器）可以创建该IPC对象，其余进程则可以指定同一个IPC对象。<br /> <br /> IPC类型&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用于打开或创建IPC的名字空间&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IPC打开后的标识<br /> 管道&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 没有名字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 描述符<br /> FIFO&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 路径名&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 描述符<br /> <br /> Posix互斥锁&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 没有名字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pthread_mutex_t指针<br /> Posix条件变量&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 没有名字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pthread_cond_t指针<br /> Posix读写锁&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 没有名字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pthread_rwlock_t指针<br />fcntl记录上锁&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 路径名&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 描述符<br /><br />Posix消息队列&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Posix IPC名字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mqd_t值<br />Posix有名信号量&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Posix IPC名字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sem_t指针<br />Posix基于内存的信号量&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 没有名字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sem_t指针<br />Posix共享内存区&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Posix IPC名字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 描述符<br /><br /><br />System V消息队列&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; key_t键&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System V IPC标识符<br />System V 信号量&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; key_t键&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System V IPC标识符<br />System V共享内存区&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; key_t键 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; System V IPC 标识符<br /><br />门 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; 路径名 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 描述符<br />sun RPC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 程序/版本 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RPC句柄<br /><br />TCP套接字 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; IP地址与TCP 端口 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 描述符<br />UDP套接字 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IP地址与UDP端口 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; 描述符<br />Unix域套接字 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; 路径名 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; 描述符 &nbsp; <br /><div></div></div><img src ="http://www.cppblog.com/tankzhouqiang/aggbug/150085.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tankzhouqiang/" target="_blank">周强</a> 2011-07-04 09:58 <a href="http://www.cppblog.com/tankzhouqiang/archive/2011/07/04/150085.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux 守护进程编写规则</title><link>http://www.cppblog.com/tankzhouqiang/archive/2011/06/29/149778.html</link><dc:creator>周强</dc:creator><author>周强</author><pubDate>Wed, 29 Jun 2011 13:50:00 GMT</pubDate><guid>http://www.cppblog.com/tankzhouqiang/archive/2011/06/29/149778.html</guid><wfw:comment>http://www.cppblog.com/tankzhouqiang/comments/149778.html</wfw:comment><comments>http://www.cppblog.com/tankzhouqiang/archive/2011/06/29/149778.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/tankzhouqiang/comments/commentRss/149778.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tankzhouqiang/services/trackbacks/149778.html</trackback:ping><description><![CDATA[<div>linux 守护进程编写规则</div><br />（1）首先要做的是调用umask将文件模式创建屏蔽字设置为0.由继承得来的文件模式创建屏蔽字可能会拒绝设置某些权限。<br />（2）调用fork，然后使父进程退出（exit）.这样做实现了下面几点：第一，如果该守护进程是作为一条简单shell命令启动的，那么父进程终止使得shell认为这条命令已经执行完毕。第二，子进程继承了父进程的进程组ID,但具有一个新的进程ID,这就保证了子进程不是一个进程组的组长进程。这对于下面就要做的setsid调用是必要的前提条件。<br />（3）调用setsid以创建一个新会话，是调用进程：（a)成为新会话的首进程，（b）成为一个新进程组的组长进程，（c）没有控制终端。在有些人建议在此时再次调用 fork,并是父进程终止。第二个子进程作为守护进程继续运行。这样就保证了该守护进程不是会话首进程。<br />（4）将当前工作目录更改为根目录。<br />（5）关闭不再需要的文件描述符。这使守护进程不再持有从其父进程继承来的某些文件描述符。<br />（6）某些守护进程打开/dev/null使其具有文件描述符0，1，2.这样，任何一个试图读标准输入，写标准输出或标准出错的库例程都不会产生任何效果。<br /><br />参考：UNIX环境高级编程<img src ="http://www.cppblog.com/tankzhouqiang/aggbug/149778.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tankzhouqiang/" target="_blank">周强</a> 2011-06-29 21:50 <a href="http://www.cppblog.com/tankzhouqiang/archive/2011/06/29/149778.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>unix进程间通信</title><link>http://www.cppblog.com/tankzhouqiang/archive/2011/04/12/144013.html</link><dc:creator>周强</dc:creator><author>周强</author><pubDate>Tue, 12 Apr 2011 03:07:00 GMT</pubDate><guid>http://www.cppblog.com/tankzhouqiang/archive/2011/04/12/144013.html</guid><wfw:comment>http://www.cppblog.com/tankzhouqiang/comments/144013.html</wfw:comment><comments>http://www.cppblog.com/tankzhouqiang/archive/2011/04/12/144013.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tankzhouqiang/comments/commentRss/144013.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tankzhouqiang/services/trackbacks/144013.html</trackback:ping><description><![CDATA[Unix进程间通信主要分为（1）消息传递 （2）同步 （3）共享内存 （4）远程调用<br>（1）消息传递主要有管道，FIFO，消息队列<br>（2）同步主要有互斥锁与条件变量，读写锁，记录锁，信号量<br>（3）共享内存<br>（4）远程调用<br><br><img src ="http://www.cppblog.com/tankzhouqiang/aggbug/144013.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tankzhouqiang/" target="_blank">周强</a> 2011-04-12 11:07 <a href="http://www.cppblog.com/tankzhouqiang/archive/2011/04/12/144013.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux下飞鸽传书实现</title><link>http://www.cppblog.com/tankzhouqiang/archive/2011/03/15/141915.html</link><dc:creator>周强</dc:creator><author>周强</author><pubDate>Tue, 15 Mar 2011 13:57:00 GMT</pubDate><guid>http://www.cppblog.com/tankzhouqiang/archive/2011/03/15/141915.html</guid><wfw:comment>http://www.cppblog.com/tankzhouqiang/comments/141915.html</wfw:comment><comments>http://www.cppblog.com/tankzhouqiang/archive/2011/03/15/141915.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tankzhouqiang/comments/commentRss/141915.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tankzhouqiang/services/trackbacks/141915.html</trackback:ping><description><![CDATA[<!--[if !mso]>
<style>
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style>
<![endif]--><!--[if gte mso 9]><xml>
<w:worddocument>
<w:view>Normal</w:view>
<w:zoom>0</w:zoom>
<w:trackmoves/>
<w:trackformatting/>
<w:punctuationkerning/>
<w:drawinggridverticalspacing>7.8 磅</w:drawinggridverticalspacing>
<w:displayhorizontaldrawinggridevery>0</w:displayhorizontaldrawinggridevery>
<w:displayverticaldrawinggridevery>2</w:displayverticaldrawinggridevery>
<w:validateagainstschemas/>
<w:saveifxmlinvalid>false</w:saveifxmlinvalid>
<w:ignoremixedcontent>false</w:ignoremixedcontent>
<w:alwaysshowplaceholdertext>false</w:alwaysshowplaceholdertext>
<w:donotpromoteqf/>
<w:lidthemeother>EN-US</w:lidthemeother>
<w:lidthemeasian>ZH-CN</w:lidthemeasian>
<w:lidthemecomplexscript>X-NONE</w:lidthemecomplexscript>
<w:compatibility>
<w:spaceforul/>
<w:balancesinglebytedoublebytewidth/>
<w:donotleavebackslashalone/>
<w:ultrailspace/>
<w:donotexpandshiftreturn/>
<w:adjustlineheightintable/>
<w:breakwrappedtables/>
<w:snaptogridincell/>
<w:wraptextwithpunct/>
<w:useasianbreakrules/>
<w:dontgrowautofit/>
<w:splitpgbreakandparamark/>
<w:dontvertaligncellwithsp/>
<w:dontbreakconstrainedforcedtables/>
<w:dontvertalignintxbx/>
<w:word11kerningpairs/>
<w:cachedcolbalance/>
<w:usefelayout/>
</w:compatibility>
<w:browserlevel>MicrosoftInternetExplorer4</w:browserlevel>
<m:mathpr>
<m:mathfont m:val="Cambria Math"/>
<m:brkbin m:val="before"/>
<m:brkbinsub m:val="&#45;-"/>
<m:smallfrac m:val="off"/>
<m:dispdef/>
<m:lmargin m:val="0"/>
<m:rmargin m:val="0"/>
<m:defjc m:val="centerGroup"/>
<m:wrapindent m:val="1440"/>
<m:intlim m:val="subSup"/>
<m:narylim m:val="undOvr"/>
</m:mathpr></w:worddocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:latentstyles deflockedstate="false" defunhidewhenused="true"
DefSemiHidden="true" defqformat="false" defpriority="99"
LatentStyleCount="267">
<w:lsdexception locked="false" priority="0" semihidden="false"
UnhideWhenUsed="false" qformat="true" name="Normal"/>
<w:lsdexception locked="false" priority="9" semihidden="false"
UnhideWhenUsed="false" qformat="true" name="heading 1"/>
<w:lsdexception locked="false" priority="9" qformat="true" name="heading 2"/>
<w:lsdexception locked="false" priority="9" qformat="true" name="heading 3"/>
<w:lsdexception locked="false" priority="9" qformat="true" name="heading 4"/>
<w:lsdexception locked="false" priority="9" qformat="true" name="heading 5"/>
<w:lsdexception locked="false" priority="9" qformat="true" name="heading 6"/>
<w:lsdexception locked="false" priority="9" qformat="true" name="heading 7"/>
<w:lsdexception locked="false" priority="9" qformat="true" name="heading 8"/>
<w:lsdexception locked="false" priority="9" qformat="true" name="heading 9"/>
<w:lsdexception locked="false" priority="39" name="toc 1"/>
<w:lsdexception locked="false" priority="39" name="toc 2"/>
<w:lsdexception locked="false" priority="39" name="toc 3"/>
<w:lsdexception locked="false" priority="39" name="toc 4"/>
<w:lsdexception locked="false" priority="39" name="toc 5"/>
<w:lsdexception locked="false" priority="39" name="toc 6"/>
<w:lsdexception locked="false" priority="39" name="toc 7"/>
<w:lsdexception locked="false" priority="39" name="toc 8"/>
<w:lsdexception locked="false" priority="39" name="toc 9"/>
<w:lsdexception locked="false" priority="35" qformat="true" name="caption"/>
<w:lsdexception locked="false" priority="10" semihidden="false"
UnhideWhenUsed="false" qformat="true" name="Title"/>
<w:lsdexception locked="false" priority="1" name="Default Paragraph Font"/>
<w:lsdexception locked="false" priority="11" semihidden="false"
UnhideWhenUsed="false" qformat="true" name="Subtitle"/>
<w:lsdexception locked="false" priority="22" semihidden="false"
UnhideWhenUsed="false" qformat="true" name="Strong"/>
<w:lsdexception locked="false" priority="20" semihidden="false"
UnhideWhenUsed="false" qformat="true" name="Emphasis"/>
<w:lsdexception locked="false" priority="59" semihidden="false"
UnhideWhenUsed="false" name="Table Grid"/>
<w:lsdexception locked="false" unhidewhenused="false" name="Placeholder Text"/>
<w:lsdexception locked="false" priority="1" semihidden="false"
UnhideWhenUsed="false" qformat="true" name="No Spacing"/>
<w:lsdexception locked="false" priority="60" semihidden="false"
UnhideWhenUsed="false" name="Light Shading"/>
<w:lsdexception locked="false" priority="61" semihidden="false"
UnhideWhenUsed="false" name="Light List"/>
<w:lsdexception locked="false" priority="62" semihidden="false"
UnhideWhenUsed="false" name="Light Grid"/>
<w:lsdexception locked="false" priority="63" semihidden="false"
UnhideWhenUsed="false" name="Medium Shading 1"/>
<w:lsdexception locked="false" priority="64" semihidden="false"
UnhideWhenUsed="false" name="Medium Shading 2"/>
<w:lsdexception locked="false" priority="65" semihidden="false"
UnhideWhenUsed="false" name="Medium List 1"/>
<w:lsdexception locked="false" priority="66" semihidden="false"
UnhideWhenUsed="false" name="Medium List 2"/>
<w:lsdexception locked="false" priority="67" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 1"/>
<w:lsdexception locked="false" priority="68" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 2"/>
<w:lsdexception locked="false" priority="69" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 3"/>
<w:lsdexception locked="false" priority="70" semihidden="false"
UnhideWhenUsed="false" name="Dark List"/>
<w:lsdexception locked="false" priority="71" semihidden="false"
UnhideWhenUsed="false" name="Colorful Shading"/>
<w:lsdexception locked="false" priority="72" semihidden="false"
UnhideWhenUsed="false" name="Colorful List"/>
<w:lsdexception locked="false" priority="73" semihidden="false"
UnhideWhenUsed="false" name="Colorful Grid"/>
<w:lsdexception locked="false" priority="60" semihidden="false"
UnhideWhenUsed="false" name="Light Shading Accent 1"/>
<w:lsdexception locked="false" priority="61" semihidden="false"
UnhideWhenUsed="false" name="Light List Accent 1"/>
<w:lsdexception locked="false" priority="62" semihidden="false"
UnhideWhenUsed="false" name="Light Grid Accent 1"/>
<w:lsdexception locked="false" priority="63" semihidden="false"
UnhideWhenUsed="false" name="Medium Shading 1 Accent 1"/>
<w:lsdexception locked="false" priority="64" semihidden="false"
UnhideWhenUsed="false" name="Medium Shading 2 Accent 1"/>
<w:lsdexception locked="false" priority="65" semihidden="false"
UnhideWhenUsed="false" name="Medium List 1 Accent 1"/>
<w:lsdexception locked="false" unhidewhenused="false" name="Revision"/>
<w:lsdexception locked="false" priority="34" semihidden="false"
UnhideWhenUsed="false" qformat="true" name="List Paragraph"/>
<w:lsdexception locked="false" priority="29" semihidden="false"
UnhideWhenUsed="false" qformat="true" name="Quote"/>
<w:lsdexception locked="false" priority="30" semihidden="false"
UnhideWhenUsed="false" qformat="true" name="Intense Quote"/>
<w:lsdexception locked="false" priority="66" semihidden="false"
UnhideWhenUsed="false" name="Medium List 2 Accent 1"/>
<w:lsdexception locked="false" priority="67" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 1 Accent 1"/>
<w:lsdexception locked="false" priority="68" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 2 Accent 1"/>
<w:lsdexception locked="false" priority="69" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 3 Accent 1"/>
<w:lsdexception locked="false" priority="70" semihidden="false"
UnhideWhenUsed="false" name="Dark List Accent 1"/>
<w:lsdexception locked="false" priority="71" semihidden="false"
UnhideWhenUsed="false" name="Colorful Shading Accent 1"/>
<w:lsdexception locked="false" priority="72" semihidden="false"
UnhideWhenUsed="false" name="Colorful List Accent 1"/>
<w:lsdexception locked="false" priority="73" semihidden="false"
UnhideWhenUsed="false" name="Colorful Grid Accent 1"/>
<w:lsdexception locked="false" priority="60" semihidden="false"
UnhideWhenUsed="false" name="Light Shading Accent 2"/>
<w:lsdexception locked="false" priority="61" semihidden="false"
UnhideWhenUsed="false" name="Light List Accent 2"/>
<w:lsdexception locked="false" priority="62" semihidden="false"
UnhideWhenUsed="false" name="Light Grid Accent 2"/>
<w:lsdexception locked="false" priority="63" semihidden="false"
UnhideWhenUsed="false" name="Medium Shading 1 Accent 2"/>
<w:lsdexception locked="false" priority="64" semihidden="false"
UnhideWhenUsed="false" name="Medium Shading 2 Accent 2"/>
<w:lsdexception locked="false" priority="65" semihidden="false"
UnhideWhenUsed="false" name="Medium List 1 Accent 2"/>
<w:lsdexception locked="false" priority="66" semihidden="false"
UnhideWhenUsed="false" name="Medium List 2 Accent 2"/>
<w:lsdexception locked="false" priority="67" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 1 Accent 2"/>
<w:lsdexception locked="false" priority="68" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 2 Accent 2"/>
<w:lsdexception locked="false" priority="69" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 3 Accent 2"/>
<w:lsdexception locked="false" priority="70" semihidden="false"
UnhideWhenUsed="false" name="Dark List Accent 2"/>
<w:lsdexception locked="false" priority="71" semihidden="false"
UnhideWhenUsed="false" name="Colorful Shading Accent 2"/>
<w:lsdexception locked="false" priority="72" semihidden="false"
UnhideWhenUsed="false" name="Colorful List Accent 2"/>
<w:lsdexception locked="false" priority="73" semihidden="false"
UnhideWhenUsed="false" name="Colorful Grid Accent 2"/>
<w:lsdexception locked="false" priority="60" semihidden="false"
UnhideWhenUsed="false" name="Light Shading Accent 3"/>
<w:lsdexception locked="false" priority="61" semihidden="false"
UnhideWhenUsed="false" name="Light List Accent 3"/>
<w:lsdexception locked="false" priority="62" semihidden="false"
UnhideWhenUsed="false" name="Light Grid Accent 3"/>
<w:lsdexception locked="false" priority="63" semihidden="false"
UnhideWhenUsed="false" name="Medium Shading 1 Accent 3"/>
<w:lsdexception locked="false" priority="64" semihidden="false"
UnhideWhenUsed="false" name="Medium Shading 2 Accent 3"/>
<w:lsdexception locked="false" priority="65" semihidden="false"
UnhideWhenUsed="false" name="Medium List 1 Accent 3"/>
<w:lsdexception locked="false" priority="66" semihidden="false"
UnhideWhenUsed="false" name="Medium List 2 Accent 3"/>
<w:lsdexception locked="false" priority="67" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 1 Accent 3"/>
<w:lsdexception locked="false" priority="68" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 2 Accent 3"/>
<w:lsdexception locked="false" priority="69" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 3 Accent 3"/>
<w:lsdexception locked="false" priority="70" semihidden="false"
UnhideWhenUsed="false" name="Dark List Accent 3"/>
<w:lsdexception locked="false" priority="71" semihidden="false"
UnhideWhenUsed="false" name="Colorful Shading Accent 3"/>
<w:lsdexception locked="false" priority="72" semihidden="false"
UnhideWhenUsed="false" name="Colorful List Accent 3"/>
<w:lsdexception locked="false" priority="73" semihidden="false"
UnhideWhenUsed="false" name="Colorful Grid Accent 3"/>
<w:lsdexception locked="false" priority="60" semihidden="false"
UnhideWhenUsed="false" name="Light Shading Accent 4"/>
<w:lsdexception locked="false" priority="61" semihidden="false"
UnhideWhenUsed="false" name="Light List Accent 4"/>
<w:lsdexception locked="false" priority="62" semihidden="false"
UnhideWhenUsed="false" name="Light Grid Accent 4"/>
<w:lsdexception locked="false" priority="63" semihidden="false"
UnhideWhenUsed="false" name="Medium Shading 1 Accent 4"/>
<w:lsdexception locked="false" priority="64" semihidden="false"
UnhideWhenUsed="false" name="Medium Shading 2 Accent 4"/>
<w:lsdexception locked="false" priority="65" semihidden="false"
UnhideWhenUsed="false" name="Medium List 1 Accent 4"/>
<w:lsdexception locked="false" priority="66" semihidden="false"
UnhideWhenUsed="false" name="Medium List 2 Accent 4"/>
<w:lsdexception locked="false" priority="67" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 1 Accent 4"/>
<w:lsdexception locked="false" priority="68" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 2 Accent 4"/>
<w:lsdexception locked="false" priority="69" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 3 Accent 4"/>
<w:lsdexception locked="false" priority="70" semihidden="false"
UnhideWhenUsed="false" name="Dark List Accent 4"/>
<w:lsdexception locked="false" priority="71" semihidden="false"
UnhideWhenUsed="false" name="Colorful Shading Accent 4"/>
<w:lsdexception locked="false" priority="72" semihidden="false"
UnhideWhenUsed="false" name="Colorful List Accent 4"/>
<w:lsdexception locked="false" priority="73" semihidden="false"
UnhideWhenUsed="false" name="Colorful Grid Accent 4"/>
<w:lsdexception locked="false" priority="60" semihidden="false"
UnhideWhenUsed="false" name="Light Shading Accent 5"/>
<w:lsdexception locked="false" priority="61" semihidden="false"
UnhideWhenUsed="false" name="Light List Accent 5"/>
<w:lsdexception locked="false" priority="62" semihidden="false"
UnhideWhenUsed="false" name="Light Grid Accent 5"/>
<w:lsdexception locked="false" priority="63" semihidden="false"
UnhideWhenUsed="false" name="Medium Shading 1 Accent 5"/>
<w:lsdexception locked="false" priority="64" semihidden="false"
UnhideWhenUsed="false" name="Medium Shading 2 Accent 5"/>
<w:lsdexception locked="false" priority="65" semihidden="false"
UnhideWhenUsed="false" name="Medium List 1 Accent 5"/>
<w:lsdexception locked="false" priority="66" semihidden="false"
UnhideWhenUsed="false" name="Medium List 2 Accent 5"/>
<w:lsdexception locked="false" priority="67" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 1 Accent 5"/>
<w:lsdexception locked="false" priority="68" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 2 Accent 5"/>
<w:lsdexception locked="false" priority="69" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 3 Accent 5"/>
<w:lsdexception locked="false" priority="70" semihidden="false"
UnhideWhenUsed="false" name="Dark List Accent 5"/>
<w:lsdexception locked="false" priority="71" semihidden="false"
UnhideWhenUsed="false" name="Colorful Shading Accent 5"/>
<w:lsdexception locked="false" priority="72" semihidden="false"
UnhideWhenUsed="false" name="Colorful List Accent 5"/>
<w:lsdexception locked="false" priority="73" semihidden="false"
UnhideWhenUsed="false" name="Colorful Grid Accent 5"/>
<w:lsdexception locked="false" priority="60" semihidden="false"
UnhideWhenUsed="false" name="Light Shading Accent 6"/>
<w:lsdexception locked="false" priority="61" semihidden="false"
UnhideWhenUsed="false" name="Light List Accent 6"/>
<w:lsdexception locked="false" priority="62" semihidden="false"
UnhideWhenUsed="false" name="Light Grid Accent 6"/>
<w:lsdexception locked="false" priority="63" semihidden="false"
UnhideWhenUsed="false" name="Medium Shading 1 Accent 6"/>
<w:lsdexception locked="false" priority="64" semihidden="false"
UnhideWhenUsed="false" name="Medium Shading 2 Accent 6"/>
<w:lsdexception locked="false" priority="65" semihidden="false"
UnhideWhenUsed="false" name="Medium List 1 Accent 6"/>
<w:lsdexception locked="false" priority="66" semihidden="false"
UnhideWhenUsed="false" name="Medium List 2 Accent 6"/>
<w:lsdexception locked="false" priority="67" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 1 Accent 6"/>
<w:lsdexception locked="false" priority="68" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 2 Accent 6"/>
<w:lsdexception locked="false" priority="69" semihidden="false"
UnhideWhenUsed="false" name="Medium Grid 3 Accent 6"/>
<w:lsdexception locked="false" priority="70" semihidden="false"
UnhideWhenUsed="false" name="Dark List Accent 6"/>
<w:lsdexception locked="false" priority="71" semihidden="false"
UnhideWhenUsed="false" name="Colorful Shading Accent 6"/>
<w:lsdexception locked="false" priority="72" semihidden="false"
UnhideWhenUsed="false" name="Colorful List Accent 6"/>
<w:lsdexception locked="false" priority="73" semihidden="false"
UnhideWhenUsed="false" name="Colorful Grid Accent 6"/>
<w:lsdexception locked="false" priority="19" semihidden="false"
UnhideWhenUsed="false" qformat="true" name="Subtle Emphasis"/>
<w:lsdexception locked="false" priority="21" semihidden="false"
UnhideWhenUsed="false" qformat="true" name="Intense Emphasis"/>
<w:lsdexception locked="false" priority="31" semihidden="false"
UnhideWhenUsed="false" qformat="true" name="Subtle Reference"/>
<w:lsdexception locked="false" priority="32" semihidden="false"
UnhideWhenUsed="false" qformat="true" name="Intense Reference"/>
<w:lsdexception locked="false" priority="33" semihidden="false"
UnhideWhenUsed="false" qformat="true" name="Book Title"/>
<w:lsdexception locked="false" priority="37" name="Bibliography"/>
<w:lsdexception locked="false" priority="39" qformat="true" name="TOC Heading"/>
</w:latentstyles>
</xml><![endif]--><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:普通表格;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-qformat:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.5pt;
mso-bidi-font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:宋体;
mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;
mso-font-kerning:1.0pt;}
</style>
<![endif]-->
<p class="MsoPlainText"><span lang="EN-US">Linux </span><span>下飞鸽传书设计实现<span lang="EN-US"></span></span></p>
<p class="MsoPlainText"><span lang="EN-US">1.</span><span>系统功能<span lang="EN-US"></span></span></p>
<p class="MsoPlainText"><span>根据飞鸽传书协议在<span lang="EN-US"> linux </span>下实现飞鸽传输程序<span lang="EN-US">,</span>并且与<span lang="EN-US"> windows </span>下飞鸽兼容。具体功能模块包括用户上线<span lang="EN-US">,</span>下线<span lang="EN-US">,</span>刷新查看在线用户<span lang="EN-US">,</span>收发消息<span lang="EN-US">,</span>传送文件<span lang="EN-US">/</span>文件夹功能模块。<span lang="EN-US"></span></span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">2.</span><span>具体实现<span lang="EN-US"></span></span></p>
<p class="MsoPlainText"><span lang="EN-US">2.1 </span><span>关键数据结构<span lang="EN-US"></span></span></p>
<p class="MsoPlainText"><span lang="EN-US">/*</span><span>命令的结构<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">typedef struct _command</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;{</span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>int version;/*</span><span>命令的版本<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>int seq;/*</span><span>包编号<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>char
srcName[100];/*</span><span>发送者姓名<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>char
srcHost[100];/*</span><span>发送者主机名<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>int flag;/*</span><span>命令<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>char
addtion[100];/*</span><span>附加字段<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;}command;</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">/*</span><span>在线用户信息<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">typedef struct _userInfo</span></p>
<p class="MsoPlainText"><span lang="EN-US">{</span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>char
name[MAXLINE];<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>/*</span><span>姓名<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>char
host[MAXLINE];<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>/*</span><span>主机名<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>char
group[MAXLINE];<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>/*</span><span>所在的组名<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>struct
sockaddr_in addr;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>/*</span><span>地址信息<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>struct
_userInfo next;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>/*</span><span>链表中下一个<span lang="EN-US">*/ </span></span></p>
<p class="MsoPlainText"><span lang="EN-US">}userInfo;</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">/*</span><span>在线用户列表<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">typedef struct _uList</span></p>
<p class="MsoPlainText"><span lang="EN-US">{</span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>userInfo
*userListHead;<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>/*</span><span>链表头<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>userInfo
userListTail;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>/*</span><span>链表尾<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">}uList;</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">/*</span><span>消息队列<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">typedef struct _mesList</span></p>
<p class="MsoPlainText"><span lang="EN-US">{</span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>command
*mesHead;</span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span>command
*mesTail;</span></p>
<p class="MsoPlainText"><span lang="EN-US">}mesList;</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">2.2 </span><span>程序主要结构<span lang="EN-US"></span></span></p>
<p class="MsoPlainText"><span>本程序主要采用多线程结构<span lang="EN-US">,</span>分为<span lang="EN-US"> receive(</span>接收消息<span lang="EN-US">), process(</span>处理收到的消息<span lang="EN-US">), sendData(</span>发送文件<span lang="EN-US">) </span>三个子线程。线程间通信互斥锁与<span lang="EN-US"> Posix </span>信号量进行通信。<span lang="EN-US"></span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><br></span><span lang="EN-US"></span></p>
<p class="MsoPlainText"><span lang="EN-US">2.3 </span><span>函数接口<span lang="EN-US"></span></span></p>
<p class="MsoPlainText"><span lang="EN-US">(1) /*</span><span>从文件描述符<span lang="EN-US">fd</span>中读取<span lang="EN-US">count</span>个字符存入<span lang="EN-US">buf</span>中<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;</span>ssize_t
readn(int fd,void *buf,size_t count)</span><span>；<span lang="EN-US"></span></span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(2) /*</span><span>将<span lang="EN-US">buf</span>所指向的存储区中的<span lang="EN-US">len</span>个字符吸入文件描述符<span lang="EN-US">fd</span>中<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;</span>ssize_t
writen(int fd,char *buf,int len);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(3) /*</span><span>用于字符串转换<span lang="EN-US">,</span>网络传输中用<span lang="EN-US">gb2312</span>编码，<span lang="EN-US">linux</span>下<span lang="EN-US">gtk</span>用<span lang="EN-US">utf-8</span>编码，需要进行转换<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;</span>int
code_convert(char *from_charset,char *to_charset,char *inbuf,int inlen,char
*outbuf,int outlen);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(4) /*</span><span>在用户链表中加入新用户信息，加入成功返回<span lang="EN-US">1</span>，否则返回<span lang="EN-US">0,</span>使用<span lang="EN-US">userInfoMutex</span>进行线程间通信控制<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp; </span>int
pushBack(uList *list,userInfo user);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(5) /*</span><span>在用户链表中删除指定地址信息的用户，删除成功后返回<span lang="EN-US">1</span>，否则返回<span lang="EN-US">0</span>，使用<span lang="EN-US">userInfoMutex</span>进行线程间控制<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp; </span>int
delUser(uList *list, struct sockaddr_in addr);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(6) /*</span><span>判断该用户是否已经存在，已经存在则返回<span lang="EN-US">1</span>，否则返回<span lang="EN-US">0,</span>使用<span lang="EN-US">userInfoMutex</span>进行线程间控制<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">int isExist(uList *list,struct sockaddr_in addr);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(7)</span><span>清空用户链表，释放空间，用于用户退出和用户刷新时释放空间<span lang="EN-US">,</span>使用<span lang="EN-US">userInfoMutex</span>进行线程间控制<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">int destroyList(uList *list);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(8)/*</span><span>创建命令字<span lang="EN-US">,com</span>为要返回的命令字<span lang="EN-US">,flag </span>为消息标志<span lang="EN-US">,addtion </span>为附加标志<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void createCmd(command &amp; com,int flag,char
addtion[])</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(9)/*</span><span>发送消息，<span lang="EN-US">com</span>为要发送的消息，<span lang="EN-US">servaddr</span>为要发送的地址，<span lang="EN-US">attach</span>为文件附件信息<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">void sendCmd(command com, struct sockaddr_in
servaddr,char attach[]);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(10) /*</span><span>把收到的消息加入到消息队列中<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void addMes(mesList *mHead,command cmd);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(11) /*</span><span>把消息队列中头部的节点消息提取出来用于处理<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">int delMes(mesList *mHead,command *cmd);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(12)/*</span><span>初始化操作，飞鸽登录时初始化消息链表，用户链表，信号量，套接字信息<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;</span>void init();</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(13)/*</span><span>登录操作<span lang="EN-US">,</span>发送用户上线消息<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void login();</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(14)/*</span><span>解析收到的消息命令，提取各个字段<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;</span>int
analysisCmd(command *cmd,char *buf);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(15) /*</span><span>接收消息线程处理函数<span lang="EN-US">,</span>将收到的消息加入消息队列中，通过信号量<span lang="EN-US">waitNoFull</span>和<span lang="EN-US">waitNoEmpty</span>和消息处理线程进行通信。消息队列用<span lang="EN-US">mesMutex</span>与其他线程进行通信，保证消息队列的正确性<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;</span>void
*receive(void *arg);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(16)/*gtk</span><span>界面中显示在线用户信息<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void showUser(uList *list);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(17)/*</span><span>在<span lang="EN-US">gtk</span>界面中显示消息<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void showMessage(char *message);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(18)/*</span><span>显示收到的信息<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void showRecvMessage(char *host,char *message);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(19)/*</span><span>分析文件的信息，提取有用的字段<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void fileAnalysis(char *recv,int *fNum,char *fName,int
*fSize,int *fTime,int *fType);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(20) /*</span><span>保存收到的单个文件<span lang="EN-US">,saveName</span>为保存的文件名<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void saveSignalFile(char *saveName);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(21)/*</span><span>分析目录附件，获得目录文件的文件名，文件大小，文件类型<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void getDirInfo(char *recv,char *fName,int *fSize,int
*fType);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(22) /*</span><span>保存目录<span lang="EN-US">,saveName</span>为要保存的目录<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void saveDir(char *saveName);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(23)/*</span><span>保存文件<span lang="EN-US">,recvType=1</span>为保存文件，<span lang="EN-US">recvType=2</span>为保存的目录<span lang="EN-US">,</span>使用<span lang="EN-US">fileMutex</span>来设置互斥性<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void saveFile();</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(24)/*</span><span>收到单个文件<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void receiveSignalFile(char *recvFileName);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(25)/*</span><span>收到单个目录<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void receiveDir(char *recvDirName);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(26)/*</span><span>接收文件<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void receiveFile(command cmd);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(27)/*</span><span>信号处理线程<span lang="EN-US">,</span>从消息队列中取出消息进行处理<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void *process(void *arg);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(28)/*</span><span>发送消息<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">int sendMes();</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(29) /*</span><span>将文件名进行转换<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">char *transName(char *fileName);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(30)/*</span><span>发送文件<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void sendFile();</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(31)/*</span><span>发送文件夹<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void sendDir();</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(32)/*</span><span>用户点击刷新<span lang="EN-US">,</span>刷新在线用户<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void refresh();</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(33) /*</span><span>用户退出<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void quit();</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(34)/*</span><span>传输文件夹数据，递归函数<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void transferDir(int fd,char *dir);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(35)/*</span><span>监听<span lang="EN-US">TCP</span>套接口，发送文件与文件夹线程<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">void *sendData(void *arg);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(36)/*</span><span>创建菜单<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">static void create_popup_menu(GtkWidget
*menu,GtkWidget *view);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(37)/*</span><span>右击选中<span lang="EN-US">treeview,</span>显示传送文件与文件夹菜单<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">static gboolean showTreeView(GtkWidget
*eventBox,GdkEventButton *event,GtkWidget *menu);</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(38)/*</span><span>选择要发送的文件<span lang="EN-US"> */</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">static void selectFile();</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(39)/*</span><span>选择要发送的文件夹<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">static void selectDir();</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">(40)/*</span><span>选择要保存的文件名或文件夹名<span lang="EN-US">*/</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">static void selectSaveFile();</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">3.</span><span>总结<span lang="EN-US"></span></span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US"><span>&nbsp;&nbsp;&nbsp; </span></span><span>实现了<span lang="EN-US">linux</span>下飞鸽传书的基本功能，并且能与<span lang="EN-US">window</span>下飞鸽进行通信，传文件。熟悉了<span lang="EN-US">linux</span>下网络编程，多线程编程及线程间通信（主要用到信号量与互斥锁）。但加密解密那块没有完成，程序结构不是很好，界面做得太差。有空应该看看设计模式<span lang="EN-US">.</span></span></p>
<p class="MsoPlainText">界面截图（界面比较垃圾)：</p>
<p class="MsoPlainText"><img  src="http://www.cppblog.com/images/cppblog_com/tankzhouqiang/Screenshot.png" border="0"><br><span><span lang="EN-US"></span></span></p>
<p class="MsoPlainText"><span><span lang="EN-US">附：</span></span></p>
<p class="MsoPlainText"><span><span lang="EN-US">飞鸽协议： http://bbs.chinaunix.net/viewthread.php?tid=1015775<br></span></span></p>
<p class="MsoPlainText"><span>&nbsp;<span lang="EN-US"></span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><br></span><span lang="EN-US"></span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoPlainText"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;</span></p><img src ="http://www.cppblog.com/tankzhouqiang/aggbug/141915.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tankzhouqiang/" target="_blank">周强</a> 2011-03-15 21:57 <a href="http://www.cppblog.com/tankzhouqiang/archive/2011/03/15/141915.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>