﻿<?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++博客-beautykingdom</title><link>http://www.cppblog.com/beautykingdom/</link><description /><language>zh-cn</language><lastBuildDate>Thu, 09 Apr 2026 05:40:23 GMT</lastBuildDate><pubDate>Thu, 09 Apr 2026 05:40:23 GMT</pubDate><ttl>60</ttl><item><title>freebsd 配置ssh的root登陆</title><link>http://www.cppblog.com/beautykingdom/archive/2012/10/12/193196.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Fri, 12 Oct 2012 01:17:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2012/10/12/193196.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/193196.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2012/10/12/193196.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/193196.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/193196.html</trackback:ping><description><![CDATA[<div><p><strong># ee /etc/ssh/sshd_config</strong></p> <p>PermitRootLogin yes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #允许root登录<br />PermitEmptyPasswords no&nbsp;&nbsp;&nbsp;&nbsp; #不允许空密码<br />PasswordAuthentication yes&nbsp; #需要密码认证</p></div><img src ="http://www.cppblog.com/beautykingdom/aggbug/193196.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2012-10-12 09:17 <a href="http://www.cppblog.com/beautykingdom/archive/2012/10/12/193196.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ubuntu设置静态ip</title><link>http://www.cppblog.com/beautykingdom/archive/2012/09/02/189133.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Sun, 02 Sep 2012 05:52:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2012/09/02/189133.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/189133.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2012/09/02/189133.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/189133.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/189133.html</trackback:ping><description><![CDATA[edit &nbsp;/etc/network/interfaces<br /><br />auto eth0<br />iface eth0 inet static<br />address ip<br />gateway default gateway<br />netmask default netmask<img src ="http://www.cppblog.com/beautykingdom/aggbug/189133.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2012-09-02 13:52 <a href="http://www.cppblog.com/beautykingdom/archive/2012/09/02/189133.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>程序员面试题精选100题(08)－求1+2+...+n[C/C++/C#] &lt;转&gt;</title><link>http://www.cppblog.com/beautykingdom/archive/2012/07/05/181446.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Thu, 05 Jul 2012 02:04:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2012/07/05/181446.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/181446.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2012/07/05/181446.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/181446.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/181446.html</trackback:ping><description><![CDATA[<p style="line-height: 25px; margin: 0px 0px 10px; padding: 0px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; text-align: left; background-color: #ffffff; "><a href="http://zhedahht.blog.163.com/blog/static/2541117420072915131422/">http://zhedahht.blog.163.com/blog/static/2541117420072915131422/</a><span style="font-family: SimSun; ">题目：求</span>1+2+&#8230;+n<span style="font-family: SimSun; ">，要求不能使用乘除法、</span>for<span style="font-family: SimSun; ">、</span>while<span style="font-family: SimSun; ">、</span>if<span style="font-family: SimSun; ">、</span>else<span style="font-family: SimSun; ">、</span>switch<span style="font-family: SimSun; ">、</span>case<span style="font-family: SimSun; ">等关键字以及条件判断语句（</span>A?B:C<span style="font-family: SimSun; ">）。</span></p><p style="line-height: 25px; margin: 0px 0px 10px; padding: 0px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; text-align: left; background-color: #ffffff; "><span style="font-family: SimSun; ">分析：这道题没有多少实际意义，因为在软件开发中不会有这么变态的限制。但这道题却能有效地考查发散思维能力，而发散思维能力能反映出对编程相关技术理解的深刻程度。</span></p><p style="line-height: 25px; margin: 0px 0px 10px; padding: 0px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; text-align: left; background-color: #ffffff; "><span style="font-family: SimSun; ">通常求</span>1+2+&#8230;+n<span style="font-family: SimSun; ">除了用公式</span>n(n+1)/2<span style="font-family: SimSun; ">之外，无外乎循环和递归两种思路。由于已经明确限制</span>for<span style="font-family: SimSun; ">和</span>while<span style="font-family: SimSun; ">的使用，循环已经不能再用了。同样，递归函数也需要用</span>if<span style="font-family: SimSun; ">语句或者条件判断语句来判断是继续递归下去还是终止递归，但现在题目已经不允许使用这两种语句了。</span></p><p style="line-height: 25px; margin: 0px 0px 10px; padding: 0px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; text-align: left; background-color: #ffffff; "><span style="font-family: SimSun; ">我们仍然围绕循环做文章。循环只是让相同的代码执行</span>n<span style="font-family: SimSun; ">遍而已，我们完全可以不用</span>for<span style="font-family: SimSun; ">和</span>while<span style="font-family: SimSun; ">达到这个效果。比如定义一个类，我们</span>new<span style="font-family: SimSun; ">一含有</span>n<span style="font-family: SimSun; ">个这种类型元素的数组，那么该类的构造函数将确定会被调用</span>n<span style="font-family: SimSun; ">次。我们可以将需要执行的代码放到构造函数里。如下代码正是基于这个思路：</span></p><p style="line-height: 25px; margin: 0px 0px 10px; padding: 0px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; text-align: left; background-color: #ffffff; "><span style="line-height: 23px; font-family: 'Courier New'; color: blue; font-size: 10pt; ">class</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;Temp<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">{<br /></span><span style="line-height: 23px; font-family: 'Courier New'; color: blue; font-size: 10pt; ">public</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">:<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Temp() { ++ N; Sum += N; }<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; "><br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue; ">static</span>&nbsp;<span style="color: blue; ">void</span>&nbsp;Reset() { N = 0; Sum = 0; }<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue; ">static</span>&nbsp;<span style="color: blue; ">int</span>&nbsp;GetSum() {&nbsp;<span style="color: blue; ">return</span>&nbsp;Sum; }<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; "><br /></span><span style="line-height: 23px; font-family: 'Courier New'; color: blue; font-size: 10pt; ">private</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">:<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue; ">static</span>&nbsp;<span style="color: blue; ">int</span>&nbsp;N;<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue; ">static</span>&nbsp;<span style="color: blue; ">int</span>&nbsp;Sum;<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">};<br /><br /></span><span style="line-height: 23px; font-family: 'Courier New'; color: blue; font-size: 10pt; ">int</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;Temp::N = 0;<br /></span><span style="line-height: 23px; font-family: 'Courier New'; color: blue; font-size: 10pt; ">int</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;Temp::Sum = 0;<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; "><br /></span><span style="line-height: 23px; font-family: 'Courier New'; color: blue; font-size: 10pt; ">int</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;solution1_Sum(<span style="color: blue; ">int</span>&nbsp;n)<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">{<br /><span style="font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Temp::Reset();<br /></span><br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Temp *a =&nbsp;<span style="color: blue; ">new</span>&nbsp;Temp[n];<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue; ">delete</span>&nbsp;[]a;<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a = 0;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp;Temp::GetSum();<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">}</span></p><p style="line-height: 25px; margin: 0px 0px 10px; padding: 0px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; text-align: left; background-color: #ffffff; "><span style="font-family: SimSun; ">我们同样也可以围绕递归做文章。既然不能判断是不是应该终止递归，我们不妨定义两个函数。一个函数充当递归函数的角色，另一个函数处理终止递归的情况，我们需要做的就是在两个函数里二选一。从二选一我们很自然的想到布尔变量，比如</span>ture<span style="font-family: SimSun; ">（</span>1<span style="font-family: SimSun; ">）的时候调用第一个函数，</span>false<span style="font-family: SimSun; ">（</span>0<span style="font-family: SimSun; ">）的时候调用第二个函数。那现在的问题是如和把数值变量</span>n<span style="font-family: SimSun; ">转换成布尔值。如果对</span>n<span style="font-family: SimSun; ">连续做两次反运算，即</span>!!n<span style="font-family: SimSun; ">，那么非零的</span>n<span style="font-family: SimSun; ">转换为</span>true<span style="font-family: SimSun; ">，</span>0<span style="font-family: SimSun; ">转换为</span>false<span style="font-family: SimSun; ">。有了上述分析，我们再来看下面的代码：</span></p><p style="line-height: 25px; margin: 0px 0px 10px; padding: 0px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; text-align: left; background-color: #ffffff; "><span style="line-height: 23px; font-family: 'Courier New'; color: blue; font-size: 10pt; ">class</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;A;<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">A* Array[2];<br /><br /></span><span style="line-height: 23px; font-family: 'Courier New'; color: blue; font-size: 10pt; ">class</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;A<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">{<br /></span><span style="line-height: 23px; font-family: 'Courier New'; color: blue; font-size: 10pt; ">public</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">:<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue; ">virtual</span>&nbsp;<span style="color: blue; ">int</span>&nbsp;Sum (<span style="color: blue; ">int</span>&nbsp;n) {&nbsp;<span style="color: blue; ">return</span>&nbsp;0; }<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">};<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; "><br /></span><span style="line-height: 23px; font-family: 'Courier New'; color: blue; font-size: 10pt; ">class</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;B:&nbsp;<span style="color: blue; ">public</span>&nbsp;A<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">{<br /></span><span style="line-height: 23px; font-family: 'Courier New'; color: blue; font-size: 10pt; ">public</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">:<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue; ">virtual</span>&nbsp;<span style="color: blue; ">int</span>&nbsp;Sum (<span style="color: blue; ">int</span>&nbsp;n) {&nbsp;<span style="color: blue; ">return</span>&nbsp;Array[!!n]-&gt;Sum(n-1)+n; }<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">};<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; "><br /></span><span style="line-height: 23px; font-family: 'Courier New'; color: blue; font-size: 10pt; ">int</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;solution2_Sum(<span style="color: blue; ">int</span>&nbsp;n)<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">{<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A a;<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;B b;<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Array[0] = &amp;a;<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Array[1] = &amp;b;<br /><br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue; ">int</span>&nbsp;value = Array[1]-&gt;Sum(n);<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; "><br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue; ">return</span>&nbsp;value;<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">}</span></p><p style="line-height: 25px; margin: 0px 0px 10px; padding: 0px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; text-align: left; background-color: #ffffff; "><span style="font-family: SimSun; ">这种方法是用虚函数来实现函数的选择。当</span>n<span style="font-family: SimSun; ">不为零时，执行函数</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">B::Sum</span><span style="font-family: SimSun; ">；当</span>n<span style="font-family: SimSun; ">为</span>0<span style="font-family: SimSun; ">时，执行</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">A::Sum</span><span style="font-family: SimSun; ">。我们也可以直接用函数指针数组，这样可能还更直接一些：</span></p><p style="line-height: 25px; margin: 0px 0px 10px; padding: 0px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; text-align: left; background-color: #ffffff; "><span style="line-height: 23px; font-family: 'Courier New'; color: blue; font-size: 10pt; ">typedef</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;<span style="color: blue; ">int</span>&nbsp;(*fun)(<span style="color: blue; ">int</span>);<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; "><br /></span><span style="line-height: 23px; font-family: 'Courier New'; color: blue; font-size: 10pt; ">int</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;solution3_f1(<span style="color: blue; ">int</span>&nbsp;i)&nbsp;<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">{<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue; ">return</span>&nbsp;0;<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">}<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; "><br /></span><span style="line-height: 23px; font-family: 'Courier New'; color: blue; font-size: 10pt; ">int</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;solution3_f2(<span style="color: blue; ">int</span>&nbsp;i)<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">{<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fun f[2]={solution3_f1, solution3_f2};&nbsp;<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue; ">return</span>&nbsp;i+f[!!i](i-1);<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">}</span></p><p style="line-height: 25px; margin: 0px 0px 10px; padding: 0px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; text-align: left; background-color: #ffffff; "><span style="line-height: 23px; font-family: SimSun; font-size: 10pt; ">另外我们还可以让编译器帮我们来完成类似于递归的运算，比如如下代码：</span></p><p style="line-height: 25px; margin: 0px 0px 10px; padding: 0px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; text-align: left; background-color: #ffffff; "><span style="line-height: 23px; font-family: 'Courier New'; color: blue; font-size: 10pt; ">template</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&lt;<span style="color: blue; ">int</span>&nbsp;n&gt;&nbsp;<span style="color: blue; ">struct</span>&nbsp;solution4_Sum<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">{<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue; ">enum</span>&nbsp;Value { N = solution4_Sum&lt;n - 1&gt;::N + n};<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">};</span></p><p style="line-height: 25px; margin: 0px 0px 10px; padding: 0px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; text-align: left; background-color: #ffffff; "></p><p style="line-height: 25px; margin: 0px 0px 10px; padding: 0px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; text-align: left; background-color: #ffffff; "><span style="line-height: 23px; font-family: 'Courier New'; color: blue; font-size: 10pt; ">template</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&lt;&gt;&nbsp;<span style="color: blue; ">struct</span>&nbsp;solution4_Sum&lt;1&gt;<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">{<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue; ">enum</span>&nbsp;Value { N = 1};<br /></span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">};</span></p><p style="line-height: 25px; margin: 0px 0px 10px; padding: 0px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; text-align: left; background-color: #ffffff; "><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">solution4_Sum&lt;100&gt;::N</span><span style="font-family: SimSun; ">就是</span>1+2+...+100<span style="font-family: SimSun; ">的结果。当编译器看到</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">solution4_Sum&lt;100&gt;</span><span style="font-family: SimSun; ">时，就是为模板类</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">solution4_Sum</span><span style="font-family: SimSun; ">以参数</span>100<span style="font-family: SimSun; ">生成该类型的代码。但以</span>100<span style="font-family: SimSun; ">为参数的类型需要得到以</span>99<span style="font-family: SimSun; ">为参数的类型，因为</span><span style="line-height: 23px; font-family: 'Courier New'; font-size: 10pt; ">solution4_Sum&lt;100&gt;::N=solution4_Sum&lt;99&gt;::N+100</span><span style="font-family: SimSun; ">。这个过程会递归一直到参数为</span>1<span style="font-family: SimSun; ">的类型，由于该类型已经显式定义，编译器无需生成，递归编译到此结束。由于这个过程是在编译过程中完成的，因此要求输入</span>n<span style="font-family: SimSun; ">必须是在编译期间就能确定，不能动态输入。这是该方法最大的缺点。而且编译器对递归编译代码的递归深度是有限制的，也就是要求</span>n<span style="font-family: SimSun; ">不能太大。</span></p><p style="line-height: 25px; margin: 0px 0px 10px; padding: 0px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; text-align: left; background-color: #ffffff; "><span style="font-family: SimSun; ">大家还有更多、更巧妙的思路吗？欢迎讨论</span>^_^</p><span style="line-height: 25px; text-align: left; background-color: #ffffff; font-family: 宋体; "><p style="margin: 0in 0in 10pt; padding: 0px; text-indent: 0.5in; ">本文已经收录到《<span style="font-family: Calibri, sans-serif; "><a target="_blank" href="http://zhedahht.blog.163.com/blog/static/254111742011101624433132/" style="text-decoration: none; color: #990000; "><span style="font-family: 宋体; ">剑指</span>Offer<span style="font-family: 宋体; ">&#8212;&#8212;名企面试官精讲典型编程题</span></a></span>》一书中，有改动。欢迎关注。我把这篇博客翻译成了英文，感兴趣的朋友可以到</p></span><a target="_blank" rel="nofollow" href="http://codercareer.blogspot.com/2011/10/no-08-calculate-12n.html" style="line-height: 25px; text-decoration: none; color: #990000; font-family: Arial, Helvetica, simsun, u5b8bu4f53; text-align: left; background-color: #ffffff; ">http://codercareer.blogspot.com/2011/10/no-08-calculate-12n.html</a><span style="line-height: 25px; text-align: left; background-color: #ffffff; font-family: 宋体; ">查看。<br /></span><p style="line-height: 25px; margin: 0in 0in 10pt; padding: 0px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; text-align: left; background-color: #ffffff; text-indent: 0.5in; "><span style="font-family: 宋体; ">博主何海涛对本博客文章享有版权。网络转载请注明出处</span><a href="http://zhedahht.blog.163.com/" style="text-decoration: none; color: #990000; ">http://zhedahht.blog.163.com/</a><span style="font-family: 宋体; ">。整理出版物请和作者联系。</span><span style="font-family: 宋体; ">对解题思路有任何建议，欢迎在评论中告知，或者加我微博</span><a rel="nofollow" href="http://t.sina.com.cn/zhedahht" style="text-decoration: none; color: #990000; ">http://weibo.com/zhedahht</a><span style="font-family: 宋体; ">或者</span><a href="http://t.163.com/zhedahht" style="text-decoration: none; color: #990000; ">http://t.163.com/zhedahht</a><span style="font-family: 宋体; ">与我讨论。谢谢。<br />from：<br /></span><a href="http://zhedahht.blog.163.com/blog/static/2541117420072915131422/">http://zhedahht.blog.163.com/blog/static/2541117420072915131422/</a></p><img src ="http://www.cppblog.com/beautykingdom/aggbug/181446.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2012-07-05 10:04 <a href="http://www.cppblog.com/beautykingdom/archive/2012/07/05/181446.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux core dump file详解 &lt;转&gt;</title><link>http://www.cppblog.com/beautykingdom/archive/2012/06/30/180911.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Sat, 30 Jun 2012 12:08:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2012/06/30/180911.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/180911.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2012/06/30/180911.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/180911.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/180911.html</trackback:ping><description><![CDATA[<span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">1. 前言: 有的程序可以通过编译, 但在运行时会出现Segment fault(段错误). 这通常都是指针错误引起的. 但这不像编译错误一样会提示到文件-&gt;行, 而是没有任何信息, 使得我们的调试变得困难起来.</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp; 2. gdb: 有一种办法是, 我们用gdb的step, 一步一步寻找. 这放在短小的代码中是可行的, 但要让你step一个上万行的代码, 我想你会从此厌恶程序员这个名字, 而把他叫做调试员. 我们还有更好的办法, 这就是core file.</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp; 3. ulimit: 如果想让系统在信号中断造成的错误时产生core文件, 我们需要在shell中按如下设置: #设置core大小为无限 ulimit -c unlimited #设置文件大小为无限 ulimit unlimited 这些需要有root权限, 在ubuntu下每次重新打开中断都需要重新输入上面的第一条命令, 来设置core大小为无限.</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp; 4. 用gdb查看core文件: 下面我们可以在发生运行时信号引起的错误时发生core dump了. 发生core dump之后, 用gdb进行查看core文件的内容, 以定位文件中引发core dump的行. gdb [exec file] [core file] 如: gdb ./test test.core 在进入gdb后, 用bt命令查看backtrace以检查发生程序运行到哪里, 来定位core dump的文件-&gt;行.</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">1. 什么是Core：</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">Sam之前一直以为Core Dump中Core是 Linux Kernel的意思. 今天才发现在这里，Core是另一种意思：</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">在使用半导体作为内存的材料前，人类是利用线圈当作内存的材料（发明者为王安），线圈就叫作 core ，用线圈做的内存就叫作 core memory。如今 ，半导体工业澎勃发展，已经没有人用 core memory 了，不过，在许多情况下， 人们还是把记忆体叫作 core 。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">2. 什么是Core Dump：</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">我们在开发（或使用）一个程序时，最怕的就是程序莫明其妙地当掉。虽然系统没事，但我们下次仍可能遇到相同的问题。于是这时操作系统就会把程序当掉 时的内存内容 dump 出来（现在通常是写在一个叫 core 的 file 里面），让 我们或是 debugger 做为参考。这个动作就叫作 core dump。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">3. Core Dump时会生成何种文件：</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">Core Dump时，会生成诸如 core.进程号 的文件。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">4. 为何有时程序Down了，却没生成 Core文件。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">Linux下，有一些设置，标明了resources available to the shell and to processes。 可以使用#ulimit -a&nbsp; 来看这些设置。 (ulimit是bash built-in Command)</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -a&nbsp;&nbsp;&nbsp;&nbsp; All current limits are reported</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -c&nbsp;&nbsp;&nbsp;&nbsp; The maximum size of core files created</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -d&nbsp;&nbsp;&nbsp;&nbsp; The maximum size of a process鈥檚 data segment</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -e&nbsp;&nbsp;&nbsp;&nbsp; The maximum scheduling priority ("nice")</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -f&nbsp;&nbsp;&nbsp;&nbsp; The maximum size of files written by the shell and its children</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -i&nbsp;&nbsp;&nbsp;&nbsp; The maximum number of pending signals</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -l&nbsp;&nbsp;&nbsp;&nbsp; The maximum size that m ay be locked into memory</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -m&nbsp;&nbsp;&nbsp;&nbsp; The maximum resident set size (has no effect on Linux)</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -n&nbsp;&nbsp;&nbsp;&nbsp; The maximum number of open file descriptors (most systems do not allow this value to be set)</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -p&nbsp;&nbsp;&nbsp;&nbsp; The pipe size in 512-byte blocks (this may not be set)</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -q&nbsp;&nbsp;&nbsp;&nbsp; The maximum number of bytes in POSIX message queues</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -r&nbsp;&nbsp;&nbsp;&nbsp; The maximum real-time scheduling priority</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -s&nbsp;&nbsp;&nbsp;&nbsp; The maximum stack size</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -t&nbsp;&nbsp;&nbsp;&nbsp; The maximum amount of cpu time in seconds</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -u&nbsp;&nbsp;&nbsp;&nbsp; The maximum number of processes available to a single user</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -v&nbsp;&nbsp;&nbsp;&nbsp; The maximum amount of virtual memory available to the shell</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -x&nbsp;&nbsp;&nbsp;&nbsp; The maximum number of file locks</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;从这里可以看出，如果 -c是显示：core file size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (blocks, -c)&nbsp; 如果这个值为0，则无法生成core文件。所以可以使用：</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">#ulimit -c 1024&nbsp;&nbsp; 或者 #ulimit -c unlimited&nbsp;&nbsp; 来使能 core文件。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">如果程序出错时生成Core 文件，则会显示Segmentation fault (core dumped) 。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">5. Core Dump的核心转储文件目录和命名规则:</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">/proc/sys/kernel /core_uses_pid可以控制产生的core文件的文件名中是否添加pid作为扩展，如果添加则文件内容为1，否则为0</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">6. 如何使用Core文件：</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">在Linux下，使用：</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">#gdb -c core.pid program_name</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">就可以进入gdb模式。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">输入where，就可以指出是在哪一行被Down掉，哪个function内，由谁调用等等。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">(gdb) where</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">或者输入 bt。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">(gdb) bt</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">7. 如何让一个正常的程序down:</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">#kill -s SIGSEGV pid</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">8. 察看Core文件输出在何处：</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">存放Coredump的目录即进程的当前目录，一般就是当初发出命令启动该进程时所在的目录。但如果是通过脚本启动，则脚本可能会修改当前目录，这时进程真正的当前目录就会与当初执行脚本所在目录不同。这时可以查看&#8221;/proc/&lt;进程pid&gt;/cwd&#8220;符号链接的目标来确定进程真正的当前目录地址。通过系统服务启动的进程也可通过这一方法查看。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">9. 嵌入式设备下如何使用Core dump:</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">linux coredump配置与调试</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">Linux</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">Core Dump 配置与调试</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">1.core文件的生成开关和大小限制</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">---------------------------------</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">1）使用ulimit -c 命令可查看core文件的生成开关。若结果为0，则表示关闭了此功能，不会生成core文件。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">2）使用ulimit -c filesize命令，可以限制core文件的大小（filesize的单位为kbyte）。若ulimit -c unlimited，则表示core文件的大小不受限制。如果生成的信息超过此大小，将会被裁剪，最终生成一个不完整的core文件。在调试此core文件的时候，gdb会提示错误。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">2.core文件的名称和生成路径</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">----------------------------</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">若系统生成的core文件不带其它任何扩展名称，则全部命名为core。新的core文件生成将覆盖原来的core文件 。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">1）/proc/sys /kernel/core_uses_pid可以控制core文件的文件名中是否添加pid作为扩展。文件内容为1，表示添加pid作为扩展名，生成的 core文件格式为core.xxxx；为0则表示生成的core文件同一命名为core。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">可通过以下命令修改此文件：</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">echo"1" &gt;/proc/sys/kernel/core_uses_pid</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">2）proc/sys/kernel/core_pattern可以控制core文件保存位置和文件名格式。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">可通过以下命令修改此文件：</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">echo"/corefile/core-%e-%p-%t" &gt;core_pattern，可以将core文件统一生成到/corefile目录下，产生的文件名为core-命令名-pid-时间戳</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">以下是参数列表:</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">%p - insert pid into filename 添加pid</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">%u - insert current uid into filename 添加当前uid</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">%g - insert current gid into filename 添加当前gid</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">%s - insert signal that caused the coredump into the filename&nbsp; 添加导致产生core的信号</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">%t - insert UNIX time that the coredump occurred into filename&nbsp; 添加core文件生成时的unix时间</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">%h - insert hostname where the coredump happened into filename&nbsp; 添加主机名</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">%e - insert coredumping executable name into filename&nbsp; 添加命令名</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">3.用gdb查看core文件:</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">下面我们可以在发生运行时信号引起的错误时发生core dump了.</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">发生 core dump之后,用gdb进行查看core文件的内容,以定位文件中引发core dump的行.</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">gdb [exec file] [core file]</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">如:gdb ./test test.core</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">在进入gdb后,用 bt命令查看backtrace以检查发生程序运行到哪里,来定位core dump的文件-&gt;行.</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">4.开发板上使用core文件调试</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-----------------------------</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">如果开发板的操作系统也是linux，core调试方法依然适用。如果开发板上不支持gdb，可将开发板的环境（头文件、库）、可执行文件和core文件拷贝到PC的linux下，运行相关命令即可。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">注意：待调试的可执行文件，在编译的时候需要加-g，core文件才能正常显示出错信息！</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">注意的问题：</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">在Linux下要保证程序崩溃时生成 Coredump要注意这些问题：</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">　　一、要保证存放Coredump的目录存在且进程对该目录有写权限。存放Coredump 的目录即进程的当前目录，一般就是当初发出命令启动该进程时所在的目录。但如果是通过脚本启动，则脚本可能会修改当前目录，这时进程真正的当前目录就会与当初执行脚本所在目录不同。这时可以查看&#8221;/proc/进程pid&gt;/cwd&#8220;符号链接的目标来确定进程真正的当前目录地址。通过系统服务启动的进程也可通过这一方法查看。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">　　二、若程序调用了seteuid()/setegid()改变了进程的有效用户或组，则在默认情况下系统不会为这些进程生成Coredump。很多服务程序都会调用seteuid()，如MySQL，不论你用什么用户运行 mysqld_safe启动MySQL，mysqld进行的有效用户始终是msyql用户。如果你当初是以用户A运行了某个程序，但在ps里看到的</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">这个程序的用户却是B的话，那么这些进程就是调用了seteuid了。为了能够让这些进程生成core dump，需要将/proc/sys/fs/suid_dumpable 文件的内容改为1（一般默认是0）。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">　　三、这个一般都知道，就是要设置足够大的Core文件大小限制了。程序崩溃时生成的 Core文件大小即为程序运行时占用的内存大小。但程序崩溃时的行为不可按平常时的行为来估计，比如缓冲区溢出等错误可能导致堆栈被破坏，因此经常会出现某个变量的值被修改成乱七八糟的，然后程序用这个大小去申请内存就可能导致程序比平常时多占用很多内存。因此无论程序正常运行时占用的内存多么少，要保证生成Core文件还是将大小限制设为unlimited为好。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">ulimit -- 用户资源限制命令</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">1、说明 :ulimit用于shell启动进程所占用的资源.</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">2、类别 :shell内建命令</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">3、语法格式 :ulimit [-acdfHlmnpsStvw] [size]</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">4、参数介绍 :</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-H 设置硬件资源限制.</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-S 设置软件资源限制.</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-a 显示当前所有的资源限制.</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-c size:设置core文件的最大值.单位:blocks</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-d size:设置数据段的最大值.单位:kbytes</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-f size:设置创建文件的最大值.单位:blocks</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-l size:设置在内存中锁定进程的最大值.单位:kbytes</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-m size:设置可以使用的常驻内存的最大值.单位:kbytes</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-n size:设置内核可以同时打开的文件描述符的最大值.单位:n</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-p size:设置管道缓冲区的最大值.单位:kbytes</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-s size:设置堆栈的最大值.单位:kbytes</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-t size:设置CPU使用时间的最大上限.单位:seconds</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-v size:设置虚拟内存的最大值.单位:kbytes 5,简单实例:&nbsp;</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">5、举例</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">在Linux下写程序的时候，如果程序比较大，经常会遇到&#8220;段错误&#8221;（segmentationfault）这样的问题，这主要就是由于Linux系统初始的堆栈大小（stack size）太小的缘故，一般为10M。我一般把stacksize设置成256M，这样就没有段错误了！命令为：ulimit&nbsp;&nbsp; -s 262140</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">如果要系统自动记住这个配置，就编辑/etc/profile文件，在 &#8220;ulimit -S -c 0 &gt; /dev/null 2&gt;&amp;1&#8221;行下，添加&#8220;ulimit&nbsp;&nbsp; -s 262140&#8221;，保存重启系统就可以了！</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">1]在RH8的环境文件/etc/profile中,我们可以看到系统是如何配置ulimit的:</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">#grep ulimit /etc/profile</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">ulimit -S -c 0 &gt; /dev/null 2&gt;&amp;1</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">这条语句设置了对软件资源和对core文件大小的设置</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">2]如果我们想要对由shell创建的文件大小作些限制,如:</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">#ll h</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-rw-r--r-- 1 lee lee 150062 7月 22 02:39 h</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">#ulimit -f 100 #设置创建文件的最大块(一块=512字节)</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">#cat h&gt;newh</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">File size limit exceeded</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">#ll newh</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-rw-r--r-- 1 lee lee 51200 11月 8 11:47 newh</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">文件h的大小是150062字节,而我们设定的创建文件的大小是512字节x100块=51200字节，当然系统就会根据你的设置生成了51200字节的newh文件.</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">3]可以像实例1]一样,把你要设置的ulimit放在/etc/profile这个环境文件中.</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">用途：设置或报告用户资源极限。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">语法：ulimit [ -H ] [ -S ] [ -a ] [ -c ] [ -d ] [ -f ] [ -m ] [ -n ] [ -s ] [ -t ] [ Limit ]</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">描述：ulimit 命令设置或报告用户进程资源极限，如 /etc/security/limits 文件所定义。文件包含以下缺省值极限：</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">fsize = 2097151</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">core = 2097151</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">cpu = -1</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">data = 262144</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">rss = 65536</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">stack = 65536</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">nofiles = 2000</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">当新用户添加到系统中时，这些值被作为缺省值使用。当向系统中添加用户时，以上值通过 mkuser 命令设置，或通过 chuser 命令更改。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">极限分为软性或硬性。通过 ulimit 命令，用户可将软极限更改到硬极限的最大设置值。要更改资源硬极限，必须拥有 root 用户权限。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">很多系统不包括以上一种或数种极限。 特定资源的极限在指定 Limit 参数时设定。Limit 参数的值可以是每个资源中指定单元中的数字，或者为值 unlimited。要将特定的 ulimit 设置为 unlimited，可使用词 unlimited。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">&nbsp;&nbsp;&nbsp; 注：在 /etc/security/limits 文件中设置缺省极限就是设置了系统宽度极限， 而不仅仅是创建用户时用户所需的极限。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">省略 Limit 参数时，将会打印出当前资源极限。除非用户指定 -H 标志，否则打印出软极限。当用户指定一个以上资源时，极限名称和单元在值之前打印。如果未给予选项，则假定带有了 -f 标志。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">由于 ulimit 命令影响当前 shell 环境，所以它将作为 shell 常规内置命令提供。如果在独立的命令执行环境中调用该命令，则不影响调用者环境的文件大小极限。以下示例中正是这种情况：</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">nohup ulimit -f 10000</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">env ulimit 10000</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">一旦通过进程减少了硬极限，若无 root 特权则无法增加，即使返回到原值也不可能。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">关于用户和系统资源极限的更多信息，请参见 AIX 5L Version 5.3 Technical Reference: BaseOperating System and Extensions Volume 1 中的 getrlimit、setrlimit 或vlimit 子例程。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">标志</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-a&nbsp;&nbsp;&nbsp;&nbsp; 列出所有当前资源极限。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-c&nbsp;&nbsp;&nbsp;&nbsp; 以 512 字节块为单位，指定核心转储的大小。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-d&nbsp;&nbsp;&nbsp;&nbsp; 以 K 字节为单位指定数据区域的大小。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-f&nbsp;&nbsp;&nbsp;&nbsp; 使用 Limit 参数时设定文件大小极限（以块计），或者在未指定参数时报告文件大小极限。缺省值为 -f 标志。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-H&nbsp;&nbsp;&nbsp;&nbsp; 指定设置某个给定资源的硬极限。如果用户拥有 root 用户权限，可以增大硬极限。任何用户均可减少硬极限。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-m&nbsp;&nbsp;&nbsp;&nbsp; 以 K 字节为单位指定物理存储器的大小。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-n&nbsp;&nbsp;&nbsp;&nbsp; 指定一个进程可以拥有的文件描述符的数量的极限。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-s&nbsp;&nbsp;&nbsp;&nbsp; 以 K 字节为单位指定堆栈的大小。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-S&nbsp;&nbsp;&nbsp;&nbsp; 指定为给定的资源设置软极限。软极限可增大到硬极限的值。如果 -H 和 -S 标志均未指定，极限适用于以上二者。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">-t&nbsp;&nbsp;&nbsp;&nbsp; 指定每个进程所使用的秒数 。</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">退出状态</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">返回以下退出值：</span><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><br style="font-family: 宋体, Arial; background-color: #f5f7f8; " /><span style="font-family: 宋体, Arial; background-color: #f5f7f8; ">0&nbsp;&nbsp;&nbsp;&nbsp; 成功完成。</span>&nbsp;<br /><br /><br />from:<br /><a href="http://blog.chinaunix.net/uid-26707720-id-3256694.html">http://blog.chinaunix.net/uid-26707720-id-3256694.html</a>&nbsp;<img src ="http://www.cppblog.com/beautykingdom/aggbug/180911.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2012-06-30 20:08 <a href="http://www.cppblog.com/beautykingdom/archive/2012/06/30/180911.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从B 树、B+ 树、B* 树谈到R 树《转》</title><link>http://www.cppblog.com/beautykingdom/archive/2012/06/30/180893.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Sat, 30 Jun 2012 09:15:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2012/06/30/180893.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/180893.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2012/06/30/180893.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/180893.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/180893.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;作者：July、weedge、Frankie。编程艺术室出品。说明：本文从B树开始谈起，然后论述B+树、B*树，最后谈到R&nbsp;树。其中B树、B+树及B*树部分由weedge完成，R&nbsp;树部分由Frankie完成，全文最终由July统稿修订完成。出处：http://blog.csdn.net/v_JULY_v&nbsp;。&nbsp;第...&nbsp;&nbsp;<a href='http://www.cppblog.com/beautykingdom/archive/2012/06/30/180893.html'>阅读全文</a><img src ="http://www.cppblog.com/beautykingdom/aggbug/180893.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2012-06-30 17:15 <a href="http://www.cppblog.com/beautykingdom/archive/2012/06/30/180893.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>苹果向求职者抛出的8大难题&lt;转&gt;</title><link>http://www.cppblog.com/beautykingdom/archive/2012/06/19/179425.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Tue, 19 Jun 2012 14:03:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2012/06/19/179425.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/179425.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2012/06/19/179425.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/179425.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/179425.html</trackback:ping><description><![CDATA[<p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">6月14日消息，苹果公司在招聘员工时，会向求职者问一些&#8220;可汗学院&#8221;（Khan Academy）提出的考验智商的谜题。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">你可能没听说过&#8220;可汗学院&#8221;，但&#8220;可汗学院&#8221;的谜题被苹果采用一定是有其道理的。可汗学院由孟加拉裔美国人萨尔曼&#8226;可汗（Salman Kahan）创立，是一家由谷歌和比尔&amp;梅琳达&#8226;盖茨基金会背后支持的教育性非营利组织，主旨在于利用网络影片进行免费授课，目前已经有关于数学、历史、金融、物理、化学、生物、天文学等科目的内容。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">苹果在面试过程中随时都有可能向求职者抛出这些考验智商与逻辑的问题，因此如果你向往进入苹果工作，这些艰涩的问题在面试前必须谨慎对待仔细研究，因为苹果的原则是&#8212;&#8212;不能出错，哪怕你已经级别很高，是冲着苹果的高级软件工程师职位而来也不例外。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">幸运的是，这些问题虽然刁钻，但却都有唯一的答案，所以你只要有备而来，还是可以应对自如的，下面是8个苹果面试过程中求职者可能遇到的问题，以及已经被各路聪明的求职者破解的答案。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; "><strong style="font-weight: 800; ">问题一：</strong></p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">&#8220;你面前有两扇门，其中一扇门内藏着宝藏，但如果你不小心闯入另一扇门，只能痛苦地慢慢死掉&#8230;&#8230;&#8221;</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">这一听就是那种经典的最令人头痛的一类问题，但其实与其他问题相比，这只是个热身。在这两扇门后面，有两个人，这两个人都知道哪扇门后有宝藏，哪扇门擅闯者死，而这两个人呢，一个人只说真话，一个人只说假话。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">谁说真话谁说假话？那就要看你有没有智慧自己找出来了，游戏规则是，你只能问这两个人每人一个问题。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">那么，你问什么问题？问哪个人？根据他们的回答，你又该怎么做？</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">求职者的最佳答案：</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">随便问其中一个人：&#8220;如果我问另一个人，他会跟我说哪扇门后是宝藏？</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">如果你问的恰好是讲真话的那个人，那他指给你的答案就是那扇通向死亡的门，因为他会诚实地告诉你那个说谎的人会怎么说。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">如果你问的是那个只说谎话的，你得到的也是错误的答案，因为另一个人是讲真话的，说谎话的人会告诉你与讲真话的人相反的答案。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">所以你只要随便问一个人上述问题，然后选择与他们说的相反的门就行了。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; "><strong style="font-weight: 800; ">问题二：</strong></p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">&#8220;你前面站了5个人，他们中间只有一个人讲真话&#8230;&#8230;&#8221;</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">这个问题比上个问题难就难在，你只知道他们五个中有一个只讲真话，但其余四个，他们有时候讲真话，有时候讲假话，只有一点可以确定，这四个人将真话和假话有个规律：如果这次讲了真话，下次就会讲假话，如果这次讲假话，下次就讲真话。你的任务是，把五个人中那个只讲真话的人找出来。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">你可以问两个问题，两个问题可以向同一个人发问，也可以分别问两个人。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">你该问什么问题？</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">小提示：你可以这样安排两个问题承担的任务：首先你可以先问一个问题，不管得到的答案是什么，你都能从中知道下一个问题你将得到的答案是真是假。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">求职者的最佳答案：</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">随便找一个人，首先问：&#8220;你是那个只讲真话的吗？&#8221;如果答案是肯定的，你再问这个人：&#8220;谁是只讲真话的？&#8221;；如果第一个问题你得到的答案是否定的，你就再问对方&#8220;谁不是只讲真话的？&#8221;</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">正如这个问题给出的提示，第一个问题的价值在于，如果你得到的答案是&#8220;我是&#8221;，那么你问的人要么是那个只讲真话的，要么是那个这一轮讲假话的&#8220;半真话半假话&#8221;者，不管是谁，他下一轮一定会说真话。所以你可以继续问这个人：&#8220;谁是只讲真话的？&#8221;对方的答案就是正确答案。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">如果对第一个问题你得到的答案是&#8220;我不是&#8221;，那么回答者不可能是只讲真话的那个人，只能是一个此轮讲真话的&#8220;半真话半假话&#8221;者。此人下一轮将会说假话，所以你应该问他：&#8220;谁不是只讲真话的？&#8221;同样他告诉你的，只能是那个只讲真话的。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; "><strong style="font-weight: 800; ">问题三：</strong></p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">&#8220;外星人打算将地球用来种蘑菇，并且已经抓了十个人类&#8230;&#8230;&#8221;</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">外星人用这十个人代表地球60亿人口，将通过外星人的方式来测试这十个人，决定地球是不是有资格加入跨星际委员会，如果没有，就把地球变成一个蘑菇农场。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">明天，这十个人将被关在一间漆黑的屋子里前后排成一队，外星人将给每个人戴一顶帽子，帽子为紫色或者绿色，然后外星人会将灯打开，这十个人每个人都无法看见自己头上的帽子是什么颜色，但可以看见排在你前面的每个人头上帽子的颜色。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">帽子的颜色是随机的，可能全是紫的，也可能全是绿的，或者是任意的组合。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">外星人会从后往前问每一个人:&#8220;你头上的帽子是什么颜色？&#8221;如果这个人答对了，这个人就安然无事，他所代表的地球上6亿人口也将获救。否则，这个人将被爆头，外星人将把他所代表的6亿人口变成蘑菇的肥料。每个人的答案屋子里所有人都可以听到。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">现在，人类的命运在你手上，你可以设计一个方案，使这十个人提前制定一个计划，这个计划必须拯救尽可能多的人。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">提示：有个方案可以让你拯救其中至少九个人。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">求职者的最佳答案：</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">第十个人计算排在前面的所有人的绿帽子是奇数还是偶数并向前面的人发出一个信号，这样排在前面人就可以再通过排在更前面的所有人的绿帽子的奇偶数是否变化来判断自己帽子的颜色，因为如果绿帽子奇偶发生变化，那自己就是那个导致变化的&#8220;绿帽子&#8221;，如果没变化，自己就是&#8220;紫帽子&#8221;。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">因为所有的人除了回答外星人的问题不能说话，所以第十个人的&#8220;信号&#8221;只能包含在自己的答案里，比如如果排在前面的九个人有奇数顶绿帽子，这个人类就告诉外星人自己的帽子是&#8220;绿色&#8221;，如果是偶数，就猜自己的帽子是&#8220;紫色&#8221;。这样等于给他前面的人一个暗号，排在他前面的这个人，可以通过计算自己前面的所有人的绿帽子的奇偶变化来判断自己的帽子是绿还是紫。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">排在最后的那个人为了大众利益没有选择，根据前面的人的帽子情况告诉外星人自己是&#8220;绿帽子&#8221;还是&#8220;紫帽子&#8221;，他的答案有1/2的几率正确，但他前面的人一定都能答对。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">还没懂？比如第十个人看到前面有奇数个绿帽子，他就告诉外星人自己的是绿色，这是他前面的人就知道他的意思是前面九个人中有奇数个绿帽子，这是第九个人再数前面八个人的，如果前面八个人中也有奇数个，那自己就是紫色帽子。第九个人告诉外星人自己是紫色帽子，第八个人就知道绿帽子没有减少还是奇数个，再数数前面七个人绿帽子数的奇偶，就可以判断自己帽子的颜色；反之，如果第九个人告诉外星人自己是绿色帽子，那第八个人就应该知道绿色帽子减少了一个由奇数变成了偶数，再看看前面所有的绿帽子情况作出判断。这样一个接一个，只要每个人都认真听后面的人的答案并在心里计算所剩绿帽子的奇偶变化，前面九个人都能获救。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">当然，你也可以计算紫色帽子的奇偶。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; "><strong style="font-weight: 800; ">问题四：</strong></p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">&#8220;100个完美的逻辑学家坐在一个房间里&#8230;&#8230;&#8221;</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">这是一个电视真人秀节目，节目里100个拥有完美无瑕逻辑思维能力的人围成一圈坐在一个房间里。在进入房间前，这100个人被告知，100个人中至少有一个人的额头是蓝色的。你可以看见别人额头的颜色，但无法看到自己的，你需要对自己额头是不是蓝色进行猜测，在房间的灯被关掉时，如果你推测出你的额头是蓝色的，你需要站起来离开房间。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">然后房间的灯被再次打开，那些认为自己额头是蓝色的人已经不在屋内。接下来灯会再次被关掉，剩下的人中推测自己额头是蓝色的离开房间，如此重复。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">问题来了，假设这100个人的额头都是蓝色的，将会发生什么情况？注意，这100个人都有完美无瑕的逻辑推理能力，他们会根据其他人的额头颜色对自己进行合理的推理和猜测。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">提示：想想看，如果100个人不全是蓝色额头，又会发生什么情况？</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">求职者的最佳答案：</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">将会出现的情况是：灯关了又开，开了又关，重复到第一百次时，所有人都同时离开。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">这是为什么呢？想想看，每个人都看见其他99个人额头是蓝色的，灯关掉后再打开，发现这99个蓝色额头的同伴都没有离开，然后灯再次关掉后打开，如此重复100遍后，所有人同时离开了房间。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">这么理解吧，假设只有一个人的额头是蓝色的，由于这100个人事先被告知至少有一个人额头是蓝色，所以这个人如果看到其他99个人额头都不是蓝色，立马就知道自己是蓝色，所以灯一关掉，这个人就会离开房间。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">如果有两个人额头是蓝色呢？</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">其中一个蓝色额头的人会想：我的额头可能是蓝色也可能不是蓝色，现在其他99个人中有一个蓝色额头的人，如果我不是蓝色，那么就只有这一个人是，那么他看到我们都不是蓝色额头就能推断出他是，那么灯一关他就会离开，我先等一下，灯再打开如果他已经走了，那就证明我的额头不是蓝色的。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">反之，如果我的额头是蓝色的，那个蓝色额头的人的想法会和我刚才的想法一样先等一等，第一次关灯他不会离开，这样如果灯开了那个蓝色额头的人还在，就证明我的额头也是蓝色的。这样第二次关灯我们俩会一起离开。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">以此类推，如果有三个人额头是蓝色，你看到另外两个人额头是蓝色，应该推算出如果自己的额头不是蓝色的话，那么灯第二次关的时候他们俩会同时离开，如果他们俩没有同时离开，那就证明我的额头是蓝色的，我应该在第三次关灯的时候离开。结果是，三个蓝色额头的人在第三次关灯的时候同时离开。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">把上述逻辑重复一百遍，你就得到了最上面的正确答案。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; "><strong style="font-weight: 800; ">问题五：</strong></p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">&#8220;你有一个横6竖6的方格&#8230;&#8230;&#8221;</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">你现在在左上第一个格子里，你的任务是移动到最右下脚的格子里，你每次只能向右或者向下移动，不能斜向移动，也不能后退。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">你能找出几种方法移动到最右下脚的格子？</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">求职者的最佳答案：</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">252种。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">从对称的角度思考这个问题。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">随便挑选一个格子，假设你从出发点有n种方法从到达与所选格子上边相邻的格子，m种方法到达与它左边相邻的格子。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">想想看，从出发点到达一个格子的方法与到达它左边和上边的格子的方法有什么关系？说对了，由于你只能向右和向下移动，到达一个格子，不是从它左边来，就是从它上边来。所以你从出发点到达一个格子的方法等于到达它上边格子的方法好到达它左边格子的方法的和相同，也就是n+m.</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">这样，参照上图，你就可以算出从出发点到达每一个格子的方法了。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; "><strong style="font-weight: 800; ">问题六：</strong></p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">&#8220;逻辑学家们围成一圈坐着，他们的额头上面画有数字&#8230;&#8230;&#8221;</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">又来一个逻辑学家围成一圈的问题，这次是这样的，三个拥有完美逻辑推理能力的人围成一圈坐在一个房间里，每个人的额头上都画着一个大于0的数字，三个人的数字各不相同，每个人都看得见其他两个人的数字，看不见自己的。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">这三个数字的情况是，其中一个数字是其他两个数字的和，已知的情况还有，其中一个逻辑学家的数字是20，一个是30。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">游戏组织者从这三个逻辑学家后面走过，并问三个人各自额头上的数字是什么。但第一轮每个逻辑学家都回答他们无法推测自己的数字是什么。游戏组织者只好进行第二轮的发问，这是为什么？你能据此猜出三个逻辑学家的数字吗？</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">求职者的最佳答案：</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">结果由第三个逻辑学家的答案而定。他们三个的数字分别是20，30和50。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">假设第二个和第三个逻辑学家额头上的数字是20和30，这时候如果第一个逻辑学家的数字是10，那么第二个逻辑学家看到其他两个人一个是10，一个是30，会想：&#8220;我要么是20，要么是40.&#8221;</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">第三个逻辑学家看到其他两个人一个是10，一个是20，会想：&#8220;我要么是30，要么是10，但我不会是10，因为每个数字都不一样，所以我应该是30.&#8221;</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">这样第三个逻辑学家就会猜出自己的数字是30了，但他没有，第一轮谁也没有准确推测出自己的数字，这说明我们的前提不正确，第一个逻辑学家的数字不是10，那么他只能是50。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; "><strong style="font-weight: 800; ">问题七：</strong></p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">&#8220;你面前有一百个灯泡，排成一排&#8230;&#8230;&#8221;</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">一百个灯泡排成一排，第一轮你把他们全都打开亮着，然后第二轮，你每隔一个灯泡关掉一个，这样所有排在偶数的灯泡都被关掉了。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">然后第三轮，你每隔两个灯泡，将开着的灯泡关掉，关掉的灯泡打开（也就是说将所有排在3的倍数的灯泡的开关状态改变）。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">以此类推，你将所有排在4的倍数的灯泡的开关状态改变，然后将排在5的倍数的灯泡开关状态改变&#8230;&#8230;</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">第100轮的时候，还有几盏灯泡亮着？</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">提示：如果你是第n轮（n大于1小于100），排在n的倍数位置的灯泡的开关状态就发生转变。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">反过来，比如第8个灯泡，当你在8的因子轮（即第1，2，4和8轮）的时候，它就会改变开关状态。所以对于第m个灯泡，如果m有奇数个因子，你的开关状态就发生奇数次变化。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">求职者的最佳答案：</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">10盏灯泡亮着，这10盏灯泡排位数都是平方数。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">根据提示已经可以看出，这个问题的实质就是找出有多少个灯泡的排位数拥有奇数个因子。每拥有一个因子，到这个因子数的那一轮时，这个灯泡就会被转换开关状态。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">比如第1轮，因为所有100个数字都有因数1，所以全部被打开；第2轮，只有那些拥有2这个因子、能被2整除的数字的灯泡转换状态被关掉；第3轮，只有那些拥有3这个因子、能被3整除的数字的灯泡被转换状态。以此类推，如果灯泡排位数拥有奇数个因子，意味着它被打开和关上奇数次，那它就最终还是被打开的状态，如果灯泡排位数拥有偶数个因子，那它最终就是被关上的状态。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">比如第1个灯泡有奇数个因子，第2个有偶数个（1，2），第3个有偶数个（1，3）第4个有奇数个（1，2，4），所以 第4个灯泡最后还是亮着的。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">最终计算得出，所有排位数为平方数的灯泡最终还是亮着的，因为这些数都拥有奇数个因子，1，4，9，16&#8230;&#8230;</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">在100以内，共有10个平方数，分别是1，4，9，16，25，36，49，64，81，100。这10个排位数的灯泡，最终都还是亮着。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; "><strong style="font-weight: 800; ">问题八：</strong></p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">&#8220;你有一个立方体，立方体的边长是3&#8230;&#8230;&#8221;</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">这个问题比前面那个从左上格子走到右下格子的问题难，因为那毕竟是个平面问题。如图所示，这次的任务是从立方体的背面左上的小立方体走到完全相对的正面右下小立方体。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">你可以往上移，也可以往下移，还可以往前移。You can move toward the front, you can move down, or you can move upward.</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">问题还是，你共有几种走法？</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">求职者的最佳答案：</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">90种，思路是将这个立方体分成&#8220;三层&#8221;。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">上面平面图的那道题的思路就是个最好的提示。你可以将这个立方体分成&#8220;三层&#8221;，粉红色代表最上面那层，紫色代表中间那层，橘红色代表下面那层。</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">现在，我们把问题变成了：从左边、右边和上边到达目标小立方体的走法共有多少（如图所示，即到达紫色中间层最右下脚方块以及橘红色最右下脚左边以及上边相邻方块的方法）？假设从起点小立方体到达终点小立方体左边相邻小立方体共有m种方法，到达右边相邻小立方体共有n种方法，到达上边相邻小立方体有r种方法，那我们需要求出来的，就是n+m+r.</p><p style="margin-top: 20px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: 宋体, arial, sans-serif; text-align: left; background-color: #ffffff; text-indent: 2em; ">按照前面那道平面题的思路和方法，你就可以一点一点计算出来我们的正确答案。<br /><br />from:<br /><a href="http://tech.qq.com/a/20120618/000071.htm?pgv_ref=aio2012&amp;ptlang=2052">http://tech.qq.com/a/20120618/000071.htm?pgv_ref=aio2012&amp;ptlang=2052</a>&nbsp;<br /></p><img src ="http://www.cppblog.com/beautykingdom/aggbug/179425.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2012-06-19 22:03 <a href="http://www.cppblog.com/beautykingdom/archive/2012/06/19/179425.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>memcached完全剖析系列教程《转》</title><link>http://www.cppblog.com/beautykingdom/archive/2012/06/16/179023.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Sat, 16 Jun 2012 01:17:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2012/06/16/179023.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/179023.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2012/06/16/179023.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/179023.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/179023.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: memcached完全剖析系列教程&#8211;1.&nbsp;memcached的基础memcached是什么？memcached&nbsp;是以LiveJournal&nbsp;旗下Danga&nbsp;Interactive&nbsp;公司的Brad&nbsp;Fitzpatric&nbsp;为首开发的一款软件。现在已成为&nbsp;豆瓣、Facebook、&nbsp;Vox&nbsp;等众...&nbsp;&nbsp;<a href='http://www.cppblog.com/beautykingdom/archive/2012/06/16/179023.html'>阅读全文</a><img src ="http://www.cppblog.com/beautykingdom/aggbug/179023.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2012-06-16 09:17 <a href="http://www.cppblog.com/beautykingdom/archive/2012/06/16/179023.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>死锁和活锁 deadlock and livelock</title><link>http://www.cppblog.com/beautykingdom/archive/2012/06/08/178097.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Fri, 08 Jun 2012 09:15:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2012/06/08/178097.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/178097.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2012/06/08/178097.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/178097.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/178097.html</trackback:ping><description><![CDATA[<div class="content" sizset="2" sizcache="13"><pre id="best-answer-content" class="reply-text mb10">一、活锁 
如果事务T1封锁了数据R，事务T2又请求封锁R，于是T2等待。T3也请求封锁R，</pre><pre class="reply-text mb10">当T1释放了R上的封锁之后系统首先批准了T3的请求，T2仍然等待。然后T4又</pre><pre class="reply-text mb10">请求封锁R，当T3释放了R上的封锁之后系统又批准了T4的请求，...，T2有可</pre><pre class="reply-text mb10">能永远等待，这就是活锁的情形,避免活锁的简单方法是采用先来先服务的策略。</pre><pre class="reply-text mb10">
二、死锁 
如果事务T1封锁了数据R1，T2封锁了数据R2，然后T1又请求封锁R2，因T2已</pre><pre class="reply-text mb10">封锁了R2，于是T1等待T2释放R2上的锁。接着T2又申请封锁R1，因T1已封锁了R1，</pre><pre class="reply-text mb10">T2也只能等待T1释放R1上的锁。这样就出现了T1在等待T2，而T2又在等待T1的局面，</pre><pre class="reply-text mb10">T1和T2两个事务永远不能结束，形成死锁。 
1. 死锁的预防
在数据库中，产生死锁的原因是两个或多个事务都已封锁了一些数据对象，然后又都</pre><pre class="reply-text mb10">请求对已为其他事务封锁的数据对象加锁，从而出现死等待。防止死锁的发生其实就</pre><pre class="reply-text mb10">是要破坏产生死锁的条件。预防死锁通常有两种方法： 
&#9312; 一次封锁法  
一次封锁法要求每个事务必须一次将所有要使用的数据全部加锁，否则就不能继续执行。

一次封锁法虽然可以有效地防止死锁的发生，但也存在问题，一次就将以后要用到的全</pre><pre class="reply-text mb10">部数据加锁，势必扩大了封锁的范围，从而降低了系统的并发度。
&#9313; 顺序封锁法 
顺序封锁法是预先对数据对象规定一个封锁顺序，所有事务都按这个顺序实行封锁。

顺序封锁法可以有效地防止死锁，但也同样存在问题。事务的封锁请求可以随着事务的</pre><pre class="reply-text mb10">执行而动态地决定，很难事先确定每一个事务要封锁哪些对象，因此也就很难按规定的</pre><pre class="reply-text mb10">顺序去施加封锁。
 
可见，在操作系统中广为采用的预防死锁的策略并不很适合数据库的特点，因此DBMS在</pre><pre class="reply-text mb10">解决死锁的问题上普遍采用的是诊断并解除死锁的方法。

 2. 死锁的诊断与解除
 
&#9312; 超时法

 如果一个事务的等待时间超过了规定的时限，就认为发生了死锁。超时法实现简单，但</pre><pre class="reply-text mb10">其不足也很明显。一是有可能误判死锁，事务因为其他原因使等待时间超过时限，系统会</pre><pre class="reply-text mb10">误认为发生了死锁。二是时限若设置得太长，死锁发生后不能及时发现。
 
&#9313; 等待图法
 
事务等待图是一个有向图G=(T,U)。 T为结点的集合，每个结点表示正运行的事务；U为</pre><pre class="reply-text mb10">边的集合，每条边表示事务等待的情况。若T1等待T2,则T1、T2之间划一条有向边，从T1</pre><pre class="reply-text mb10">指向T2。事务等待图动态地反映了所有事务的等待情况。并发控制子系统周期性地（比如</pre><pre class="reply-text mb10">每隔1分钟）检测事务等待图，如果发现图中存在回路，则表示系统中出现了死锁。
 
DBMS的并发控制子系统一旦检测到系统中存在死锁，就要设法解除。通常采用的方法是选择</pre><pre class="reply-text mb10">一个处理死锁代价最小的事务，将其撤消，释放此事务持有的所有的锁，使其它事务得以继续</pre><pre class="reply-text mb10">运行下去。当然，对撤消的事务所执行的数据修改操作必须加以恢复。</pre></div><img src ="http://www.cppblog.com/beautykingdom/aggbug/178097.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2012-06-08 17:15 <a href="http://www.cppblog.com/beautykingdom/archive/2012/06/08/178097.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>IT公司笔试算法题</title><link>http://www.cppblog.com/beautykingdom/archive/2012/06/03/177318.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Sun, 03 Jun 2012 04:02:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2012/06/03/177318.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/177318.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2012/06/03/177318.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/177318.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/177318.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: from:http://blog.csdn.net/zhsenl/article/details/7515279&nbsp;1、将一整数逆序后放入一数组中（要求递归实现）void convert(int *result, int n) {&nbsp;if(n&gt;=10)&nbsp;&nbsp;convert(result+1, n/10);&nbsp;*result = n%10;&nbsp;...&nbsp;&nbsp;<a href='http://www.cppblog.com/beautykingdom/archive/2012/06/03/177318.html'>阅读全文</a><img src ="http://www.cppblog.com/beautykingdom/aggbug/177318.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2012-06-03 12:02 <a href="http://www.cppblog.com/beautykingdom/archive/2012/06/03/177318.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>effective c++</title><link>http://www.cppblog.com/beautykingdom/archive/2012/06/01/177068.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Fri, 01 Jun 2012 07:00:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2012/06/01/177068.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/177068.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2012/06/01/177068.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/177068.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/177068.html</trackback:ping><description><![CDATA[to be continued<br />最近该回顾下这本书了觉得，整本书会写一篇博客。看个差不多了就会开始写的。看完了书总是要留下些东西的。<img src ="http://www.cppblog.com/beautykingdom/aggbug/177068.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2012-06-01 15:00 <a href="http://www.cppblog.com/beautykingdom/archive/2012/06/01/177068.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为 C/C++ 项目构建您自己的内存管理器&lt;forward&gt;</title><link>http://www.cppblog.com/beautykingdom/archive/2012/05/26/176285.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Sat, 26 May 2012 14:41:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2012/05/26/176285.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/176285.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2012/05/26/176285.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/176285.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/176285.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Arpan Sen, 技术负责人, Synapti Computer Aided Design Pvt LtdRahul Kumar Kardam&nbsp;(rahul@syncad.com), 高级软件工程师, Synapti Computer Aided Design Pvt Ltd简介：&nbsp; 代码的性能优化是一项非常重要的工作。经常可以看到，采用 C 或 C++ 编写的、功能正确的...&nbsp;&nbsp;<a href='http://www.cppblog.com/beautykingdom/archive/2012/05/26/176285.html'>阅读全文</a><img src ="http://www.cppblog.com/beautykingdom/aggbug/176285.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2012-05-26 22:41 <a href="http://www.cppblog.com/beautykingdom/archive/2012/05/26/176285.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Comparing Two High-Performance I/O Design Patterns&lt;forward&gt;</title><link>http://www.cppblog.com/beautykingdom/archive/2012/05/21/175576.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Mon, 21 May 2012 03:24:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2012/05/21/175576.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/175576.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2012/05/21/175576.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/175576.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/175576.html</trackback:ping><description><![CDATA[<span style="font-size: 18px; color: #212324; font-family: Arial, Helvetica, sans-serif; line-height: normal; background-color: #ffffff; ">by Alexander Libman with Vladimir Gilbourd</span><br style="color: #212324; font-family: Arial, Helvetica, sans-serif; line-height: normal; background-color: #ffffff; font-size: medium; " /><span style="font-size: 15px; color: #212324; font-family: Arial, Helvetica, sans-serif; line-height: normal; background-color: #ffffff; ">November 25, 2005</span>&nbsp;<br /><br /><div style="padding-left: 38px; padding-right: 38px; padding-bottom: 1em; color: #212324; font-family: Arial, Helvetica, sans-serif; line-height: normal; background-color: #ffffff; font-size: medium; "><div style="font-size: 1.25em; ">Summary</div>This article investigates and compares different design patterns of high performance TCP-based servers. In addition to existing approaches, it proposes a scalable single-codebase, multi-platform solution (with code examples) and describes its fine-tuning on different platforms. It also compares performance of Java, C# and C++ implementations of proposed and existing solutions.</div><p style="color: #212324; font-family: Arial, Helvetica, sans-serif; line-height: normal; background-color: #ffffff; font-size: medium; ">System I/O can be blocking, or non-blocking synchronous, or non-blocking asynchronous [<a href="http://www.artima.com/articles/io_design_patterns3.html#resources" style="color: #800080; text-decoration: none; ">1</a>,&nbsp;<a href="http://www.artima.com/articles/io_design_patterns3.html#resources" style="color: #800080; text-decoration: none; ">2</a>]. Blocking I/O means that the calling system does not return control to the caller until the operation is finished. As a result, the caller is blocked and cannot perform other activities during that time. Most important, the caller thread cannot be reused for other request processing while waiting for the I/O to complete, and becomes a wasted resource during that time. For example, a<code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; ">read()</code>&nbsp;operation on a socket in blocking mode will not return control if the socket buffer is empty until some data becomes available.</p><p style="color: #212324; font-family: Arial, Helvetica, sans-serif; line-height: normal; background-color: #ffffff; font-size: medium; ">By contrast, a non-blocking synchronous call returns control to the caller immediately. The caller is not made to wait, and the invoked system immediately returns one of two responses: If the call was executed and the results are ready, then the caller is told of that. Alternatively, the invoked system can tell the caller that the system has no resources (no data in the socket) to perform the requested action. In that case, it is the responsibility of the caller may repeat the call until it succeeds. For example, a&nbsp;<code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; ">read()</code>&nbsp;operation on a socket in non-blocking mode may return the number of read bytes or a special return code -1 with errno set to&nbsp;<code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; ">EWOULBLOCK/EAGAIN</code>, meaning "not ready; try again later."</p><p style="color: #212324; font-family: Arial, Helvetica, sans-serif; line-height: normal; background-color: #ffffff; font-size: medium; ">In a non-blocking asynchronous call, the calling function returns control to the caller immediately, reporting that the requested action was started. The calling system will execute the caller's request using additional system resources/threads and will notify the caller (by callback for example), when the result is ready for processing. For example, a Windows&nbsp;<code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; ">ReadFile()</code>&nbsp;or POSIX&nbsp;<code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; ">aio_read()</code>&nbsp;API returns immediately and initiates an internal system read operation. Of the three approaches, this non-blocking asynchronous<span style="font-family: Arial; font-size: 14pt; "> </span><span style="font-family: Arial; font-size: 12pt; ">approach offers the best scalability and performance.</span></p><p style="color: #212324; font-family: Arial, Helvetica, sans-serif; line-height: normal; background-color: #ffffff; font-size: medium; "><span style="font-family: Arial; font-size: 12pt; ">This article investigates different non-blocking I/O multiplexing mechanisms and proposes a single multi-platform design pattern/solution. We hope that this article will help developers of high performance TCP based servers to choose optimal design solution. We also compare the performance of Java, C# and C++ implementations of proposed and existing solutions. We will exclude the blocking approach from further discussion and </span>comparison at all, as it the least effective approach for scalability and performance.<br /></p><h1>Reactor and Proactor: two I/O multiplexing approaches</h1><p><span style="font-size: 12pt; ">In general, I/O</span><span style="font-size: 12pt; "> multiplexing mechanisms rely on an event demultiplexor [</span><a href="http://www.artima.com/articles/io_design_patterns3.html#resources" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">1</span></a><span style="font-size: 12pt; ">,&nbsp;</span><a href="http://www.artima.com/articles/io_design_patterns3.html#resources" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">3</span></a><span style="font-size: 12pt; ">], an object that dispatches I/O events from a limited number of sources to the appropriate read/write event handlers. The developer registers interest in specific events and provides event handlers, or callbacks.</span><span style="font-size: 12pt; "> The event demultiplexor delivers the requested events to the event handlers.</span></p><p><span style="font-size: 12pt; ">Two patterns that involve event demultiplexors are called Reactor and Proactor [</span><a href="http://www.artima.com/articles/io_design_patterns3.html#resources" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">1</span></a><span style="font-size: 12pt; ">]. The Reactor patterns involve synchronous I/O, whereas the Proactor pattern involves asynchronous I/O. In Reactor, the event demultiplexor waits for events that indicate when a file descriptor or socket is ready for a read or write operation. The demultiplexor passes this event to the appropriate handler, which is responsible for performing the actual read or write.</span></p><p><span style="font-size: 12pt; ">In the Proactor pattern, by contrast, the handler&#8212;or the event demultiplexor on behalf of the handler&#8212;initiates asynchronous read and write operations. The I/O operation itself is performed by the operating system (OS). The parameters passed to the OS include the addresses of user-defined data buffers from which the OS gets data to write, or to which the OS puts data read. The event demultiplexor waits for events that indicate the completion of the I/O operation, and forwards those events to the appropriate handlers. For example, on Windows a handler could initiate async I/O (overlapped in Microsoft terminology) operations, and the event demultiplexor could wait for IOCompletion events [</span><a href="http://www.artima.com/articles/io_design_patterns3.html#resources" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">1</span></a><span style="font-size: 12pt; ">]. The implementation of this classic asynchronous pattern is based on an asynchronous OS-level API, and we will call this implementation the "system-level" or "true" async, because the application fully relies on the OS to execute actual I/O.</span></p><p><span style="font-size: 12pt; ">An example will help you understand the difference between Reactor and Proactor. We will focus on the read operation here, as the write implementation is similar. Here's a read in Reactor:</span></p><ul><li><span style="font-size: 12pt; ">An event handler declares interest in I/O events that indicate readiness for read on a particular socket</span></li><li><span style="font-size: 12pt; ">The event demultiplexor waits for events</span></li><li><span style="font-size: 12pt; ">An event comes in and wakes-up the demultiplexor, and the demultiplexor calls the appropriate handler</span></li><li><span style="font-size: 12pt; ">The event handler performs the actual read operation, handles the data read, declares renewed interest in I/O events, and returns control to the dispatcher</span></li></ul><p><span style="font-size: 12pt; ">By comparison, here is a read operation in Proactor (true async):</span></p><ul><li><span style="font-size: 12pt; ">A handler initiates an asynchronous read operation (note: the OS must support asynchronous I/O). In this case, the handler does not care about I/O readiness events, but is instead registers interest in receiving completion events.</span></li><li><span style="font-size: 12pt; ">The event demultiplexor waits until the operation is completed</span></li><li><span style="font-size: 12pt; ">While the event demultiplexor waits, the OS executes the read operation in a parallel kernel thread, puts data into a user-defined buffer, and notifies the event demultiplexor that the read is complete</span></li><li><span style="font-size: 12pt; ">The event demultiplexor calls the appropriate handler;</span></li><li><span style="font-size: 12pt; ">The event handler handles the data from user defined buffer, starts a new asynchronous operation, and returns control to the event demultiplexor.</span></li></ul><h1>Current practice</h1><p><span style="font-size: 12pt; ">The open-source C++ development framework ACE [</span><a href="http://www.artima.com/articles/io_design_patterns3.html#resources" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">1</span></a><span style="font-size: 12pt; ">,&nbsp;</span><a href="http://www.artima.com/articles/io_design_patterns3.html#resources" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">3</span></a><span style="font-size: 12pt; ">] developed by Douglas Schmidt, et al., offers a wide range of platform-independent, low-level concurrency support classes (threading, mutexes, etc). On the top level it provides two separate groups of classes: implementations of the ACE Reactor and ACE Proactor. Although both of them are based on platform-independent primitives, these tools offer different interfaces.</span></p><p><span style="font-size: 12pt; ">The ACE Proactor gives much better performance and robustness on MS-Windows, as Windows provides a very efficient async API, based on operating-system-level support [</span><a href="http://www.artima.com/articles/io_design_patterns3.html#resources" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">4</span></a><span style="font-size: 12pt; ">,&nbsp;</span><a href="http://www.artima.com/articles/io_design_patterns3.html#resources" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">5</span></a><span style="font-size: 12pt; ">].</span></p><p><span style="font-size: 12pt; ">Unfortunately, not all operating systems provide full robust async OS-level support. For instance, many Unix systems do not. Therefore, ACE Reactor is a preferable solution in UNIX (currently UNIX does not have robust async facilities for sockets). As a result, to achieve the best performance on each system, developers of networked applications need to maintain two separate code-bases: an ACE Proactor based solution on Windows and an ACE Reactor based solution for Unix-based systems.</span></p><p><span style="font-size: 12pt; ">As we mentioned, the true async Proactor pattern requires operating-system-level support. Due to the differing nature of event handler and operating-system interaction, it is difficult to create common, unified external interfaces for both Reactor and Proactor patterns. That, in turn, makes it hard to create a fully portable development framework and encapsulate the interface and OS- related differences.</span></p><h1>Proposed solution</h1><p><span style="font-size: 12pt; ">In this section, we will propose a solution to the challenge of designing a portable framework for the Proactor and Reactor I/O patterns. To demonstrate this solution, we will transform a Reactor demultiplexor I/O solution to an emulated async I/O by moving read/write operations from event handlers inside the demultiplexor (this is "emulated async" approach). The following example illustrates that conversion for a read operation:</span></p><blockquote style="color: #212324; background-color: #ffffff; "><ul><li><span style="font-size: 12pt; ">An event handler declares interest in I/O events (readiness for read) and provides the demultiplexor with information such as the address of a data buffer, or the number of bytes to read.</span></li><li><span style="font-size: 12pt; ">Dispatcher waits for events (for example, on&nbsp;</span><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">select()</span></code><span style="font-size: 12pt; ">);</span></li><li><span style="font-size: 12pt; ">When an event arrives, it awakes up the dispatcher. The dispatcher performs a non- blocking read operation (it has all necessary information to perform this operation) and on completion calls the appropriate handler.</span></li><li><span style="font-size: 12pt; ">The event handler handles data from the user-defined buffer, declares new interest, along with information about where to put the data buffer and the number bytes to read in I/O events. The event handler then returns control to the dispatcher.</span></li></ul></blockquote><p><span style="font-size: 12pt; ">As we can see, by adding functionality to the demultiplexor I/O pattern, we were able to convert the Reactor pattern to a Proactor pattern. In terms of the amount of work performed, this approach is exactly the same as the Reactor pattern. We simply shifted responsibilities between different actors. There is no performance degradation because the amount of work performed is still the same. The work was simply performed by different actors. The following lists of steps demonstrate that each approach performs an equal amount of work:</span></p><p><span style="font-size: 12pt; ">Standard/classic Reactor:</span></p><ul><li><span style="font-size: 12pt; ">Step 1) wait for event (Reactor job)</span></li><li><span style="font-size: 12pt; ">Step 2) dispatch "Ready-to-Read" event to user handler ( Reactor job)</span></li><li><span style="font-size: 12pt; ">Step 3) read data (user handler job)</span></li><li><span style="font-size: 12pt; ">Step 4) process data ( user handler job)</span></li></ul><p><span style="font-size: 12pt; ">Proposed emulated Proactor:</span></p><ul><li><span style="font-size: 12pt; ">Step 1) wait for event (Proactor job)</span></li><li><span style="font-size: 12pt; ">Step 2) read data (now Proactor job)</span></li><li><span style="font-size: 12pt; ">Step 3) dispatch "Read-Completed" event to user handler (Proactor job)</span></li><li><span style="font-size: 12pt; ">Step 4) process data (user handler job)</span></li></ul><p><span style="font-size: 12pt; ">With an operating system that does not provide an async I/O API, this approach allows us to hide the reactive nature of available socket APIs and to expose a fully proactive async interface. This allows us to create a fully portable platform-independent solution with a common external interface.</span></p><h1>TProactor</h1><p><span style="font-size: 12pt; ">The proposed solution (TProactor) was developed and implemented at Terabit P/L [</span><a href="http://www.artima.com/articles/io_design_patterns3.html#resources" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">6</span></a><span style="font-size: 12pt; ">]. The solution has two alternative implementations, one in C++ and one in Java. The C++ version was built using ACE cross-platform low-level primitives and has a common unified async proactive interface on all platforms.</span></p><p><span style="font-size: 12pt; ">The main TProactor components are the Engine and WaitStrategy interfaces. Engine manages the async operations lifecycle. WaitStrategy manages concurrency strategies. WaitStrategy depends on Engine and the two always work in pairs. Interfaces between Engine and WaitStrategy are strongly defined.</span></p><p><span style="font-size: 12pt; ">Engines and waiting strategies are implemented as pluggable class-drivers (for the full list of all implemented Engines and corresponding WaitStrategies, see Appendix 1). TProactor is a highly configurable solution. It internally implements three engines (POSIX AIO, SUN AIO and Emulated AIO) and hides six different waiting strategies, based on an asynchronous kernel API (for POSIX- this is not efficient right now due to internal POSIX AIO API problems) and synchronous Unix&nbsp;</span><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">select()</span></code><span style="font-size: 12pt; ">,&nbsp;</span><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">poll()</span></code><span style="font-size: 12pt; ">, /dev/poll (Solaris 5.8+),&nbsp;</span><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">port_get</span></code><span style="font-size: 12pt; ">&nbsp;(Solaris 5.10), RealTime (RT) signals (Linux 2.4+), epoll (Linux 2.6), k-queue (FreeBSD) APIs. TProactor conforms to the standard ACE Proactor implementation interface. That makes it possible to develop a single cross-platform solution (POSIX/MS-WINDOWS) with a common (ACE Proactor) interface.</span></p><p><span style="font-size: 12pt; ">With a set of mutually interchangeable "lego-style" Engines and WaitStrategies, a developer can choose the appropriate internal mechanism (engine and waiting strategy) at run time by setting appropriate configuration parameters. These settings may be specified according to specific requirements, such as the number of connections, scalability, and the targeted OS. If the operating system supports async API, a developer may use the true async approach, otherwise the user can opt for an emulated async solutions built on different sync waiting strategies. All of those strategies are hidden behind an emulated async fa&#231;ade.</span></p><p><span style="font-size: 12pt; ">For an HTTP server running on Sun Solaris, for example, the /dev/poll or&nbsp;</span><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">port_get()</span></code><span style="font-size: 12pt; ">-based engines is the most suitable choice, able to serve huge number of connections, but for another UNIX solution with a limited number of connections but high throughput requirements, a</span><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">select()</span></code><span style="font-size: 12pt; ">-based engine may be a better approach. Such flexibility cannot be achieved with a standard ACE Reactor/Proactor, due to inherent algorithmic problems of different wait strategies (see Appendix 2).</span></p><p><span style="font-size: 12pt; ">In terms of performance, our tests show that emulating from reactive to proactive does not impose any overhead&#8212;it can be faster, but not slower. According to our test results, the TProactor gives on average of up to 10-35 % better performance (measured in terms of both throughput and response times) than the reactive model in the standard ACE Reactor implementation on various UNIX/Linux platforms. On Windows it gives the same performance as standard ACE Proactor.</span></p><h1>Performance comparison (JAVA versus C++ versus C#).</h1><p><span style="font-size: 12pt; ">In addition to C++, as we also implemented TProactor in Java. As for JDK version 1.4, Java provides only the sync-based approach that is logically similar to C&nbsp;</span><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">select()</span></code><span style="font-size: 12pt; ">&nbsp;[</span><a href="http://www.artima.com/articles/io_design_patterns3.html#resources" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">7</span></a><span style="font-size: 12pt; ">,&nbsp;</span><a href="http://www.artima.com/articles/io_design_patterns3.html#resources" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">8</span></a><span style="font-size: 12pt; ">]. Java TProactor is based on Java's non-blocking facilities (java.nio packages) logically similar to C++ TProactor with waiting strategy based on&nbsp;</span><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">select()</span></code><span style="font-size: 12pt; ">.</span></p><p><span style="font-size: 12pt; ">Figures 1 and 2 chart the transfer rate in bits/sec versus the number of connections. These charts represent comparison results for a simple echo-server built on standard ACE Reactor, using RedHat Linux 9.0, TProactor C++ and Java (IBM 1.4JVM) on Microsoft's Windows and RedHat Linux9.0, and a C# echo-server running on the Windows operating system. Performance of native AIO APIs is represented by "Async"-marked curves; by emulated AIO (TProactor)&#8212;AsyncE curves; and by TP_Reactor&#8212;Synch curves. All implementations were bombarded by the same client application&#8212;a continuous stream of arbitrary fixed sized messages via N connections.</span></p><p><span style="font-size: 12pt; ">The full set of tests was performed on the same hardware. Tests on different machines proved that relative results are consistent.</span></p><div style="margin-top: 0.75em; text-align: center; "><img src="http://www.artima.com/articles/images/io_dp_fig_1.gif" alt="" /></div><div style="margin-top: 0.75em; margin-bottom: 0.75em; text-align: center; font-weight: bold; "><span style="font-size: 12pt; ">Figure 1. Windows XP/P4 2.6GHz HyperThreading/512 MB RAM.</span></div><div style="margin-top: 0.75em; text-align: center; "><img src="http://www.artima.com/articles/images/io_dp_fig_2.gif" alt="" /></div><div style="margin-top: 0.75em; margin-bottom: 0.75em; text-align: center; font-weight: bold; "><span style="font-size: 12pt; ">Figure 2. Linux RedHat 2.4.20-smp/P4 2.6GHz HyperThreading/512 MB RAM.</span></div><h1>User code example</h1><p><span style="font-size: 12pt; ">The following is the skeleton of a simple TProactor-based Java echo-server. In a nutshell, the developer only has to implement the two interfaces:&nbsp;</span><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">OpRead</span></code><span style="font-size: 12pt; ">&nbsp;with buffer where TProactor puts its read results, and&nbsp;</span><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">OpWrite</span></code><span style="font-size: 12pt; ">&nbsp;with a buffer from which TProactor takes data. The developer will also need to implement protocol-specific logic via providing callbacks&nbsp;</span><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">onReadCompleted()</span></code><span style="font-size: 12pt; ">&nbsp;and&nbsp;</span><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">onWriteCompleted()</span></code><span style="font-size: 12pt; ">&nbsp;in the&nbsp;</span><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">AsynchHandler</span></code><span style="font-size: 12pt; ">&nbsp;interface implementation. Those callbacks will be asynchronously called by TProactor on completion of read/write operations and executed on a thread pool space provided by TProactor (the developer doesn't need to write his own pool).</span></p><pre style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; padding-left: 38px; "><div><span style="font-size: 12px;">class EchoServerProtocol implements AsynchHandler</span></div><div><span style="font-size: 12px;">{</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; AsynchChannel achannel = null;</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; EchoServerProtocol(Demultiplexor m, SelectableChannel channel)</span><span style="font-size: 12px; "> throws Exception&nbsp;</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; {</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp; &nbsp; this.achannel = new AsynchChannel( m, this, channel );</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; }</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">    public void start() throws Exception</span></div><div><span style="font-size: 12px;">    {</span></div><div><span style="font-size: 12px;">	// called after construction&nbsp;</span></div><div><span style="font-size: 12px;">	System.out.println( Thread.currentThread().getName() + ": EchoServer protocol started" );&nbsp;</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp; &nbsp; achannel.read( buffer);</span></div><div><span style="font-size: 12px;">    }</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">    public void onReadCompleted( OpRead opRead ) throws Exception</span></div><div><span style="font-size: 12px;">    {</span></div><div><span style="font-size: 12px;">	if (opRead.getError() != null )</span></div><div><span style="font-size: 12px;">	{</span></div><div>&nbsp;&nbsp;&nbsp;<span style="font-size: 12px;">	// handle error, do clean-up if needed &nbsp;</span></div><div><span style="font-size: 12px;">		System.out.println( "EchoServer::readCompleted: " + opRead.getError().toString());</span></div><div><span style="font-size: 12px;">		achannel.close();</span></div><div><span style="font-size: 12px;">		return;</span></div><div><span style="font-size: 12px;">	}</span></div><div><span style="font-size: 12px; ">		</span></div><div><span style="font-size: 12px;">	if (opRead.getBytesCompleted () &lt;= 0)</span></div><div><span style="font-size: 12px;">	{</span></div><div><span style="font-size: 12px;">		System.out.println( "EchoServer::readCompleted: Peer closed " + opRead.getBytesCompleted();</span></div><div><span style="font-size: 12px;">		achannel.close();</span></div><div><span style="font-size: 12px;">		return;</span></div><div><span style="font-size: 12px;">	}</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">	ByteBuffer buffer = opRead.getBuffer();</span></div><div><span style="font-size: 12px;">	achannel.write(buffer);</span></div><div><span style="font-size: 12px;">}</span></div><div><span style="font-size: 12px; ">		</span></div><div><span style="font-size: 12px;">public void onWriteCompleted(OpWrite opWrite) throws Exception&nbsp;</span></div><div><span style="font-size: 12px;">{</span></div><div><span style="font-size: 12px;">// logically similar to onReadCompleted &nbsp; &nbsp; &nbsp; &nbsp; ... &nbsp; &nbsp;&nbsp;</span></div><div><span style="font-size: 12px;">}</span></div><div><span style="font-size: 12px;">};</span></div></pre><p><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">IOHandler</span></code><span style="font-size: 12pt; ">&nbsp;is a TProactor base class.&nbsp;</span><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">AsynchHandler</span></code><span style="font-size: 12pt; ">&nbsp;and Multiplexor, among other things, internally execute the wait strategy chosen by the developer.</span></p><h1>Conclusion</h1><p><span style="font-size: 12pt; ">TProactor provides a common, flexible, and configurable solution for multi-platform high- performance communications development. All of the problems and complexities mentioned in Appendix 2, are hidden from the developer.</span></p><p><span style="font-size: 12pt; ">It is clear from the charts that C++ is still the preferable approach for high performance communication solutions, but Java on Linux comes quite close. However, the overall Java performance was weakened by poor results on Windows. One reason for that may be that the Java 1.4 nio package is based on&nbsp;</span><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">select()</span></code><span style="font-size: 12pt; ">-style API. � It is true, Java NIO package is kind of Reactor pattern based on&nbsp;</span><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">select()</span></code><span style="font-size: 12pt; ">-style API (see [</span><a href="http://www.artima.com/articles/io_design_patterns3.html#resources" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">7</span></a><span style="font-size: 12pt; ">,&nbsp;</span><a href="http://www.artima.com/articles/io_design_patterns3.html#resources" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">8</span></a><span style="font-size: 12pt; ">]). Java NIO allows to write your own&nbsp;</span><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">select()</span></code><span style="font-size: 12pt; ">-style provider (equivalent of TProactor waiting strategies). Looking at Java NIO implementation for Windows (to do this enough to examine import symbols in jdk1.5.0\jre\bin\nio.dll), we can make a conclusion that Java NIO 1.4.2 and 1.5.0 for Windows is based on WSAEventSelect () API. That is better than&nbsp;</span><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">select()</span></code><span style="font-size: 12pt; ">, but slower than IOCompletionPort�s for significant number of connections. . Should the 1.5 version of Java's nio be based on IOCompletionPorts, then that should improve performance. If Java NIO would use IOCompletionPorts, than conversion of Proactor pattern to Reactor pattern should be made inside nio.dll. Although such conversion is more complicated than Reactor- &gt;Proactor conversion, but it can be implemented in frames of Java NIO interfaces. (this the topic of next arcticle, but we can provide algorithm). At this time, no TProactor performance tests were done on JDK 1.5.</span></p><p><span style="font-size: 12pt; ">Note. All tests for Java are performed on "raw" buffers (java.nio.ByteBuffer) without data processing.</span></p><p><span style="font-size: 12pt; ">Taking into account the latest activities to develop robust AIO on Linux [</span><a href="http://www.artima.com/articles/io_design_patterns3.html#resources" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">9</span></a><span style="font-size: 12pt; ">], we can conclude that Linux Kernel API (io_xxxx set of system calls) should be more scalable in comparison with POSIX standard, but still not portable. In this case, TProactor with new Engine/Wait Strategy pair, based on native LINUX AIO can be easily implemented to overcome portability issues and to cover Linux native AIO with standard ACE Proactor interface.</span></p><h1>Appendix I</h1><p><span style="font-size: 12pt; ">Engines and waiting strategies implemented in TProactor</span></p><p>&nbsp;</p><center><table border="1"><tbody><tr bgcolor="#CCCCFF"><th>Engine Type</th><th>Wait Strategies</th><th>Operating System</th></tr><tr></tr><tr valign="top"><td>POSIX_AIO (true async)<br /><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; ">aio_read()</code>/<code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; ">aio_write()</code></td><td><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; ">aio_suspend()<br />Waiting for RT signal<br />Callback function</code></td><td>POSIX complained UNIX (not robust)<br />POSIX (not robust)<br />SGI IRIX, LINUX (not robust)</td></tr><tr valign="top"><td>SUN_AIO (true async)<br /><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; ">aio_read()</code>/<code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; ">aio_write()</code></td><td><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; ">aio_wait()</code></td><td>SUN (not robust)</td></tr><tr valign="top"><td>Emulated Async<br />Non-blocking&nbsp;<code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; ">read()</code>/<code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; ">write()</code></td><td><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; ">select()</code><br /><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; ">poll()</code><br />/dev/poll<br />Linux RT signals<br />Kqueue</td><td>generic POSIX<br />Mostly all POSIX implementations<br />SUN<br />Linux<br />FreeBSD<br /></td></tr></tbody></table></center><h1>Appendix II</h1><p><span style="font-size: 12pt; ">All sync waiting strategies can be divided into two groups:</span></p><ul><li><span style="font-size: 12pt; ">edge-triggered (e.g. Linux RT signals)&#8212;signal readiness only when socket became ready (changes state);</span></li><li><span style="font-size: 12pt; ">level-triggered (e.g.&nbsp;</span><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">select()</span></code><span style="font-size: 12pt; ">,&nbsp;</span><code style="font-family: 'Lucida Console', 'American Typewriter', 'Courier New', Courier, monospace; font-size: 0.95em; "><span style="font-size: 12pt; ">poll()</span></code><span style="font-size: 12pt; ">, /dev/poll)&#8212;readiness at any time.</span></li></ul><p><span style="font-size: 12pt; ">Let us describe some common logical problems for those groups:</span></p><ul><li><span style="font-size: 12pt; ">edge-triggered group: after executing I/O operation, the demultiplexing loop can lose the state of socket readiness. Example: the "read" handler did not read whole chunk of data, so the socket remains still ready for read. But the demultiplexor loop will not receive next notification.</span></li><li><span style="font-size: 12pt; ">level-triggered group: when demultiplexor loop detects readiness, it starts the write/read user defined handler. But before the start, it should remove socket descriptior from the set of monitored descriptors. Otherwise, the same event can be dispatched twice.</span></li><li><span style="font-size: 12pt; ">Obviously, solving these problems adds extra complexities to development. All these problems were resolved internally within TProactor and the developer should not worry about those details, while in the synch approach one needs to apply extra effort to resolve them.</span></li></ul><a name="resources"><h1>Resources</h1></a><p><span style="font-size: 12pt; ">[1] Douglas C. Schmidt, Stephen D. Huston "C++ Network Programming." 2002, Addison-Wesley ISBN 0-201-60464-7</span><br /></p><p><span style="font-size: 12pt; ">[2] W. Richard Stevens "UNIX Network Programming" vol. 1 and 2, 1999, Prentice Hill, ISBN 0-13- 490012-X&nbsp;</span><br /></p><p><span style="font-size: 12pt; ">[3] Douglas C. Schmidt, Michael Stal, Hans Rohnert, Frank Buschmann "Pattern-Oriented Software Architecture: Patterns for Concurrent and Networked Objects, Volume 2" Wiley &amp; Sons, NY 2000</span><br /></p><p><span style="font-size: 12pt; ">[4] INFO: Socket Overlapped I/O Versus Blocking/Non-blocking Mode. Q181611. Microsoft Knowledge Base Articles.</span><br /></p><p><span style="font-size: 12pt; ">[5] Microsoft MSDN. I/O Completion Ports.</span><br /><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/i_o_completion_ports.asp" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">http://msdn.microsoft.com/library/default.asp?url=/library/en- us/fileio/fs/i_o_completion_ports.asp</span></a></p><p><span style="font-size: 12pt; ">[6] TProactor (ACE compatible Proactor).</span><br /><a href="http://www.artima.com/articles/www.terabit.com.au" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">www.terabit.com.au</span></a></p><p><span style="font-size: 12pt; ">[7] JavaDoc java.nio.channels</span><br /><a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/package-summary.html" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/package-summary.html</span></a></p><p><span style="font-size: 12pt; ">[8] JavaDoc Java.nio.channels.spi Class SelectorProvider&nbsp;</span><br /><a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/spi/SelectorProvider.html" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/spi/SelectorProvider.html</span></a></p><p><span style="font-size: 12pt; ">[9] Linux AIO development&nbsp;</span><br /><a href="http://lse.sourceforge.net/io/aio.html" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">http://lse.sourceforge.net/io/aio.html</span></a><span style="font-size: 12pt; ">, and</span><br /><a href="http://archive.linuxsymposium.org/ols2003/Proceedings/All-Reprints/Reprint-Pulavarty-OLS2003.pdf" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">http://archive.linuxsymposium.org/ols2003/Proceedings/All-Reprints/Reprint-Pulavarty-OLS2003.pdf</span></a></p><p><span style="font-size: 12pt; ">See Also:</span></p><p><span style="font-size: 12pt; ">Ian Barile "I/O Multiplexing &amp; Scalable Socket Servers", 2004 February, DDJ&nbsp;</span><br /></p><p><span style="font-size: 12pt; ">Further reading on event handling</span><br /><a href="http://www.cs.wustl.edu/~schmidt/ACE-papers.html" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">- http://www.cs.wustl.edu/~schmidt/ACE-papers.html</span></a></p><p><span style="font-size: 12pt; ">The Adaptive Communication Environment</span><br /><a href="http://www.cs.wustl.edu/~schmidt/ACE.html" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">http://www.cs.wustl.edu/~schmidt/ACE.html</span></a></p><p><span style="font-size: 12pt; ">Terabit Solutions</span><br /><a href="http://terabit.com.au/solutions.php" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">http://terabit.com.au/solutions.php</span></a></p><h1>About the authors</h1><p><span style="font-size: 12pt; ">Alex Libman has been programming for 15 years. During the past 5 years his main area of interest is pattern-oriented multiplatform networked programming using C++ and Java. He is big fan and contributor of ACE.</span></p><p><span style="font-size: 12pt; ">Vlad Gilbourd works as a computer consultant, but wishes to spend more time listening jazz :) As a hobby, he started and runs</span><a href="http://www.corporatenews.com.au/" style="color: #800080; text-decoration: none; "><span style="font-size: 12pt; ">www.corporatenews.com.au</span></a><span style="font-size: 12pt; ">&nbsp;website.</span></p><br /><br />from:<br /><a href="http://www.artima.com/articles/io_design_patterns.html">http://www.artima.com/articles/io_design_patterns.html</a> <p>&nbsp;</p><img src ="http://www.cppblog.com/beautykingdom/aggbug/175576.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2012-05-21 11:24 <a href="http://www.cppblog.com/beautykingdom/archive/2012/05/21/175576.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>boost 库 enable_shared_from_this 实现原理分析&lt;转&gt;</title><link>http://www.cppblog.com/beautykingdom/archive/2012/05/20/175469.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Sun, 20 May 2012 07:37:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2012/05/20/175469.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/175469.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2012/05/20/175469.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/175469.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/175469.html</trackback:ping><description><![CDATA[<div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">使用情景：当类对象被 shared_ptr 管理时，需要在类自己定义的函数里把当前类对象作为参数传给其他函数时，这时需要传递一个 shared_ptr ，否则就不能保持 shared_ptr 管理这个类对象的语义（因为有一个 raw pointer 指向这个类对象，而 shared_ptr 对类对象的这个引用没有计数，很有可能 shared_ptr 已经把类对象资源释放了，而那个调用函数还在使用类对象&#8212;&#8212;显然，这肯定会产生错误）。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">很好奇这个模板类的实现。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">先看看怎么使用：</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">对一个类 A ，当我们希望使用 shared_ptr 来管理其类对象时，而且需要在自己定义的函数里把类对象 shared_ptr （为什么不用普通指针，当我们使用智能指针管理资源时，必须统一使用智能指针，而不能在某些地方使用智能指针某些地方使用 raw pointer ，否则不能保持智能指针的语义，从而产生各种错误）传给其他函数时，可以让类 A 从 enable_shared_from_this 继承：</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">class A : public boost::enable_shared_from_this&lt;A&gt; {</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">};</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">然后在类 A 中需要传递类对象本身 shared_ptr 的地方使用 shared_from_this 函数来获得指向自身的 shared_ptr 。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">一个非常有代表性的例子：</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "><a target="_blank" href="http://www.boost.org/doc/libs/1_39_0/doc/html/boost_asio/tutorial/tutdaytime3/src.html" style="color: #002280; text-decoration: none; ">http://www.boost.org/doc/libs/1_39_0/doc/html/boost_asio/tutorial/tutdaytime3/src.html</a></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">另《Beyond the C++ Standard Library》 shared_ptr 节也有很简单明了的例子。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">实现原理：</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">首先要考虑的是：在类对象本身当中不能存储类对象本身的 shared_ptr ，否则类对象 shared_ptr 永远也不会为0了，从而这些资源永远不会释放，除非程序结束。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">其次：类对象肯定是外部函数通过某种机制分配的，而且一经分配立即交给 shared_ptr 管理（再次强调一遍：给 shared_ptr 管理的资源必须在分配时交给 shared_ptr&nbsp;），而且以后凡是需要共享使用类对象的地方必须使用这个 shared_ptr 当作右值来构造产生或者拷贝产生另一个 shared_ptr 从而达到共享使用的目的。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">有了以上两点的限制，要实现我们的目标（即在类对象内部使用类对象的 shared_ptr&nbsp;）有以下两种方案：</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">1、类对象的外部 shared_ptr 作为函数参数传给类的需要引用类对象自身的函数&#8212;&#8212;显然，这种方法很丑陋，而且并不是所有的情况都可行（如在外部 shared_ptr 不可见的作用域中就不行）；</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">2、类对象自身存储某种信息，在需要自身 shared_ptr 时来产生一个临时的 shared_ptr 。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">显然，第2种方法更优雅（对于用户来说），关键是信息怎么存储？</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">对了， weak_ptr ！</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">实际上， boost 中就是这样实现的。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">但现在的问题是：何时初始化这个 weak_ptr ？因为类对象生成时还没有生成相应的用来管理这个对象的 shared_ptr 。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">boost 1.39.0 中是这样实现的：</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">首先生成类 A ：会依次调用 enable_shared_from_this 的构造函数（定义为 protected ），以及类 A 的构造函数。在调用 enable_shared_from_this 的构造函数时，会初始化定义在 enable_shared_from_this 中的 weak_ptr （调用其默认构造函数），这时这个 weak_ptr 是无效的（或者说不指向任何对象）。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">接着：外部程序会把指向类 A 对象的指针作为初始化参数来初始化一个 shared_ptr 。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">现在来看看 shared_ptr 是如何初始化的， shared_ptr 定义了如下构造函数：</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">template&lt;class Y&gt;</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>explicit shared_ptr( Y * p ): px( p ), pn( p )&nbsp;<wbr></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>{</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>boost::detail::sp_enable_shared_from_this( this, p, p );</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>}</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">里面调用了 &nbsp;<wbr>boost::detail::sp_enable_shared_from_this ：</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">template&lt; class X, class Y, class T &gt;</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>inline void sp_enable_shared_from_this( boost::shared_ptr&lt;X&gt; const * ppx,</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>Y const * py, boost::enable_shared_from_this&lt; T &gt; const * pe )</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">{</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>if( pe != 0 )</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>{</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>pe-&gt;_internal_accept_owner( ppx, const_cast&lt; Y* &gt;( py ) );</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>}</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">}</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">里面又调用了 enable_shared_from_this 的 _internal_accept_owner ：</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">template&lt;class X, class Y&gt; void _internal_accept_owner( shared_ptr&lt;X&gt; const * ppx, Y * py ) const</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>{</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>if( weak_this_.expired() )</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>{</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>weak_this_ = shared_ptr&lt;T&gt;( *ppx, py );</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>}</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">&nbsp;<wbr>&nbsp;<wbr>&nbsp;&nbsp;<wbr>}</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">而在这里对 enable_shared_from_this 的成员 weak_ptr 进行拷贝赋值，使得整个 weak_ptr 作为类对象 &nbsp;<wbr>shared_ptr 的一个观察者。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">这时，当类对象本身需要自身的 shared_ptr 时，就可以从这个 weak_ptr 来生成一个了。</div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; "></div><div style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; color: #333333; background-color: #f0f8ff; ">原来如此。<br /><br /><br />from:<br /><a href="http://hi.baidu.com/jrckkyy/blog/item/0ef30b12778cdac5c2fd783b.html">http://blog.sina.com.cn/s/blog_62cd38470100g3dd.html</a><br /><br /><a href="http://hi.baidu.com/jrckkyy/blog/item/0ef30b12778cdac5c2fd783b.html">http://hi.baidu.com/jrckkyy/blog/item/0ef30b12778cdac5c2fd783b.html</a>&nbsp;<br /><br /><br /><br /><br /><br /><br /><br /></div><img src ="http://www.cppblog.com/beautykingdom/aggbug/175469.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2012-05-20 15:37 <a href="http://www.cppblog.com/beautykingdom/archive/2012/05/20/175469.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Which is asymptotically larger: lg(lg* n) or lg*(lg n)$? &lt;&lt;convert&gt;&gt;</title><link>http://www.cppblog.com/beautykingdom/archive/2012/04/15/171537.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Sun, 15 Apr 2012 12:12:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2012/04/15/171537.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/171537.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2012/04/15/171537.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/171537.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/171537.html</trackback:ping><description><![CDATA[from:<br /><br /><a href="http://math.stackexchange.com/questions/55720/which-is-asymptotically-larger-lglg-n-or-lglg-n">http://math.stackexchange.com/questions/55720/which-is-asymptotically-larger-lglg-n-or-lglg-n</a><img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/beautykingdom/2.jpg" width="675" height="273" /><br /><br /><img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/beautykingdom/1.JPG" width="663" height="498" /><br /><br /><br /><img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/beautykingdom/3.jpg" width="676" height="124" /><br /><br /><img src ="http://www.cppblog.com/beautykingdom/aggbug/171537.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2012-04-15 20:12 <a href="http://www.cppblog.com/beautykingdom/archive/2012/04/15/171537.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>TCMalloc : Thread-Caching Malloc</title><link>http://www.cppblog.com/beautykingdom/archive/2012/04/04/170077.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Wed, 04 Apr 2012 13:15:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2012/04/04/170077.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/170077.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2012/04/04/170077.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/170077.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/170077.html</trackback:ping><description><![CDATA[<h1 style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; font-family: Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">from:&nbsp;</h1>
<h1 style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; font-family: Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><a href="http://goog-perftools.sourceforge.net/doc/tcmalloc.html"><span style="font-size: 12pt">http://goog-perftools.sourceforge.net/doc/tcmalloc.html</span></a></h1>
<p style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; font-family: Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&nbsp;</p>
<h1 style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; font-family: Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">TCMalloc : Thread-Caching Malloc</h1>
<address style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; text-indent: 0px; letter-spacing: normal; font-family: Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); font-size: medium; font-weight: normal; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Sanjay Ghemawat, Paul Menage &lt;opensource@google.com&gt;</address>
<h2 style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; font-family: Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Motivation</h2><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; display: inline !important; font: medium Simsun; white-space: normal; orphans: 2; float: none; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">TCMalloc is faster than the glibc 2.3 malloc (available as a separate library called ptmalloc2) and other mallocs that I have tested. ptmalloc2 takes approximately 300 nanoseconds to execute a malloc/free pair on a 2.8 GHz P4 (for small objects). The TCMalloc implementation takes approximately 50 nanoseconds for the same operation pair. Speed is important for a malloc implementation because if malloc is not fast enough, application writers are inclined to write their own custom free lists on top of malloc. This can lead to extra complexity, and more memory usage unless the application writer is very careful to appropriately size the free lists and scavenge idle objects out of the free list</span> 
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">TCMalloc also reduces lock contention for multi-threaded programs. For small objects, there is virtually zero contention. For large objects, TCMalloc tries to use fine grained and efficient spinlocks. ptmalloc2 also reduces lock contention by using per-thread arenas but there is a big problem with ptmalloc2's use of per-thread arenas. In ptmalloc2 memory can never move from one arena to another. This can lead to huge amounts of wasted space. For example, in one Google application, the first phase would allocate approximately 300MB of memory for its data structures. When the first phase finished, a second phase would be started in the same address space. If this second phase was assigned a different arena than the one used by the first phase, this phase would not reuse any of the memory left after the first phase and would add another 300MB to the address space. Similar memory blowup problems were also noticed in other applications.</p>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Another benefit of TCMalloc is space-efficient representation of small objects. For example, N 8-byte objects can be allocated while using space approximately<span class="Apple-converted-space">&nbsp;</span><code>8N * 1.01</code><span class="Apple-converted-space">&nbsp;</span>bytes. I.e., a one-percent space overhead. ptmalloc2 uses a four-byte header for each object and (I think) rounds up the size to a multiple of 8 bytes and ends up using<span class="Apple-converted-space">&nbsp;</span><code>16N</code><span class="Apple-converted-space">&nbsp;</span>bytes.</p>
<h2 style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; font-family: Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Usage</h2>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">To use TCmalloc, just link tcmalloc into your application via the "-ltcmalloc" linker flag.</p>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">You can use tcmalloc in applications you didn't compile yourself, by using LD_PRELOAD:</p><pre style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; orphans: 2; color: rgb(0,0,0); font-weight: normal; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">   $ LD_PRELOAD="/usr/lib/libtcmalloc.so" <binary>
</binary></pre>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">LD_PRELOAD is tricky, and we don't necessarily recommend this mode of usage.</p>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">TCMalloc includes a<span class="Apple-converted-space">&nbsp;</span><a href="http://goog-perftools.sourceforge.net/doc/heap_checker.html">heap checker</a><span class="Apple-converted-space">&nbsp;</span>and<span class="Apple-converted-space">&nbsp;</span><a href="http://goog-perftools.sourceforge.net/doc/heap_profiler.html">heap profiler</a><span class="Apple-converted-space">&nbsp;</span>as well.</p>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">If you'd rather link in a version of TCMalloc that does not include the heap profiler and checker (perhaps to reduce binary size for a static binary), you can link in<span class="Apple-converted-space">&nbsp;</span><code>libtcmalloc_minimal</code><span class="Apple-converted-space">&nbsp;</span>instead.</p>
<h2 style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; font-family: Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Overview</h2><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; display: inline !important; font: medium Simsun; white-space: normal; orphans: 2; float: none; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">TCMalloc assigns each thread a thread-local cache. Small allocations are satisfied from the thread-local cache. Objects are moved from central data structures into a thread-local cache as needed, and periodic garbage collections are used to migrate memory back from a thread-local cache into the central data structures.</span> 
<center style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><img src="http://goog-perftools.sourceforge.net/doc/overview.gif"  alt="" /></center>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">TCMalloc treates objects with size &lt;= 32K ("small" objects) differently from larger objects. Large objects are allocated directly from the central heap using a page-level allocator (a page is a 4K aligned region of memory). I.e., a large object is always page-aligned and occupies an integral number of pages.</p>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">A run of pages can be carved up into a sequence of small objects, each equally sized. For example a run of one page (4K) can be carved up into 32 objects of size 128 bytes each.</p>
<h2 style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; font-family: Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Small Object Allocation</h2><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; display: inline !important; font: medium Simsun; white-space: normal; orphans: 2; float: none; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Each small object size maps to one of approximately 170 allocatable size-classes. For example, all allocations in the range 961 to 1024 bytes are rounded up to 1024. The size-classes are spaced so that small sizes are separated by 8 bytes, larger sizes by 16 bytes, even larger sizes by 32 bytes, and so forth. The maximal spacing (for sizes &gt;= ~2K) is 256 bytes.</span> 
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">A thread cache contains a singly linked list of free objects per size-class.</p>
<center style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><img src="http://goog-perftools.sourceforge.net/doc/threadheap.gif"  alt="" /></center><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; display: inline !important; font: medium Simsun; white-space: normal; orphans: 2; float: none; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">When allocating a small object: (1) We map its size to the corresponding size-class. (2) Look in the corresponding free list in the thread cache for the current thread. (3) If the free list is not empty, we remove the first object from the list and return it. When following this fast path, TCMalloc acquires no locks at all. This helps speed-up allocation significantly because a lock/unlock pair takes approximately 100 nanoseconds on a 2.8 GHz Xeon.</span> 
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">If the free list is empty: (1) We fetch a bunch of objects from a central free list for this size-class (the central free list is shared by all threads). (2) Place them in the thread-local free list. (3) Return one of the newly fetched objects to the applications.</p>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">If the central free list is also empty: (1) We allocate a run of pages from the central page allocator. (2) Split the run into a set of objects of this size-class. (3) Place the new objects on the central free list. (4) As before, move some of these objects to the thread-local free list.</p>
<h2 style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; font-family: Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Large Object Allocation</h2><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; display: inline !important; font: medium Simsun; white-space: normal; orphans: 2; float: none; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">A large object size (&gt; 32K) is rounded up to a page size (4K) and is handled by a central page heap. The central page heap is again an array of free lists. For<span class="Apple-converted-space">&nbsp;</span></span><code style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; white-space: normal; orphans: 2; color: rgb(0,0,0); font-weight: normal; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">i &lt; 256</code><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; display: inline !important; font: medium Simsun; white-space: normal; orphans: 2; float: none; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">, the<span class="Apple-converted-space">&nbsp;</span></span><code style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; white-space: normal; orphans: 2; color: rgb(0,0,0); font-weight: normal; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">k</code><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; display: inline !important; font: medium Simsun; white-space: normal; orphans: 2; float: none; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">th entry is a free list of runs that consist of<span class="Apple-converted-space">&nbsp;</span></span><code style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; white-space: normal; orphans: 2; color: rgb(0,0,0); font-weight: normal; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">k</code><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; display: inline !important; font: medium Simsun; white-space: normal; orphans: 2; float: none; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><span class="Apple-converted-space">&nbsp;</span>pages. The<span class="Apple-converted-space">&nbsp;</span></span><code style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; white-space: normal; orphans: 2; color: rgb(0,0,0); font-weight: normal; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">256</code><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; display: inline !important; font: medium Simsun; white-space: normal; orphans: 2; float: none; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">th entry is a free list of runs that have length<span class="Apple-converted-space">&nbsp;</span></span><code style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; white-space: normal; orphans: 2; color: rgb(0,0,0); font-weight: normal; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">&gt;= 256</code><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; display: inline !important; font: medium Simsun; white-space: normal; orphans: 2; float: none; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><span class="Apple-converted-space">&nbsp;</span>pages:</span> 
<center style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><img src="http://goog-perftools.sourceforge.net/doc/pageheap.gif"  alt="" /></center>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">An allocation for<span class="Apple-converted-space">&nbsp;</span><code>k</code><span class="Apple-converted-space">&nbsp;</span>pages is satisfied by looking in the<span class="Apple-converted-space">&nbsp;</span><code>k</code>th free list. If that free list is empty, we look in the next free list, and so forth. Eventually, we look in the last free list if necessary. If that fails, we fetch memory from the system (using sbrk, mmap, or by mapping in portions of /dev/mem).</p>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">If an allocation for<span class="Apple-converted-space">&nbsp;</span><code>k</code><span class="Apple-converted-space">&nbsp;</span>pages is satisfied by a run of pages of length &gt;<span class="Apple-converted-space">&nbsp;</span><code>k</code>, the remainder of the run is re-inserted back into the appropriate free list in the page heap.</p>
<h2 style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; font-family: Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Spans</h2><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; display: inline !important; font: medium Simsun; white-space: normal; orphans: 2; float: none; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">The heap managed by TCMalloc consists of a set of pages. A run of contiguous pages is represented by a<span class="Apple-converted-space">&nbsp;</span></span><code style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; white-space: normal; orphans: 2; color: rgb(0,0,0); font-weight: normal; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Span</code><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; display: inline !important; font: medium Simsun; white-space: normal; orphans: 2; float: none; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><span class="Apple-converted-space">&nbsp;</span>object. A span can either be<span class="Apple-converted-space">&nbsp;</span></span><em style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: red; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">allocated</em><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; display: inline !important; font: medium Simsun; white-space: normal; orphans: 2; float: none; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">, or<span class="Apple-converted-space">&nbsp;</span></span><em style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: red; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">free</em><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; display: inline !important; font: medium Simsun; white-space: normal; orphans: 2; float: none; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">. If free, the span is one of the entries in a page heap linked-list. If allocated, it is either a large object that has been handed off to the application, or a run of pages that have been split up into a sequence of small objects. If split into small objects, the size-class of the objects is recorded in the span.</span> 
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">A central array indexed by page number can be used to find the span to which a page belongs. For example, span<span class="Apple-converted-space">&nbsp;</span><em style="font-style: normal; color: red">a</em><span class="Apple-converted-space">&nbsp;</span>below occupies 2 pages, span<span class="Apple-converted-space">&nbsp;</span><em style="font-style: normal; color: red">b</em><span class="Apple-converted-space">&nbsp;</span>occupies 1 page, span<span class="Apple-converted-space">&nbsp;</span><em style="font-style: normal; color: red">c</em><span class="Apple-converted-space">&nbsp;</span>occupies 5 pages and span<span class="Apple-converted-space">&nbsp;</span><em style="font-style: normal; color: red">d</em><span class="Apple-converted-space">&nbsp;</span>occupies 3 pages.</p>
<center style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><img src="http://goog-perftools.sourceforge.net/doc/spanmap.gif"  alt="" /></center><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; display: inline !important; font: medium Simsun; white-space: normal; orphans: 2; float: none; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">A 32-bit address space can fit 2^20 4K pages, so this central array takes 4MB of space, which seems acceptable. On 64-bit machines, we use a 3-level radix tree instead of an array to map from a page number to the corresponding span pointer.</span> 
<h2 style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; font-family: Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Deallocation</h2><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; display: inline !important; font: medium Simsun; white-space: normal; orphans: 2; float: none; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">When an object is deallocated, we compute its page number and look it up in the central array to find the corresponding span object. The span tells us whether or not the object is small, and its size-class if it is small. If the object is small, we insert it into the appropriate free list in the current thread's thread cache. If the thread cache now exceeds a predetermined size (2MB by default), we run a garbage collector that moves unused objects from the thread cache into central free lists.</span> 
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">If the object is large, the span tells us the range of pages covered by the object. Suppose this range is<span class="Apple-converted-space">&nbsp;</span><code>[p,q]</code>. We also lookup the spans for pages<span class="Apple-converted-space">&nbsp;</span><code>p-1</code><span class="Apple-converted-space">&nbsp;</span>and<code>q+1</code>. If either of these neighboring spans are free, we coalesce them with the<span class="Apple-converted-space">&nbsp;</span><code>[p,q]</code><span class="Apple-converted-space">&nbsp;</span>span. The resulting span is inserted into the appropriate free list in the page heap.</p>
<h2 style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; font-family: Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Central Free Lists for Small Objects</h2><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; display: inline !important; font: medium Simsun; white-space: normal; orphans: 2; float: none; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">As mentioned before, we keep a central free list for each size-class. Each central free list is organized as a two-level data structure: a set of spans, and a linked list of free objects per span.</span> 
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">An object is allocated from a central free list by removing the first entry from the linked list of some span. (If all spans have empty linked lists, a suitably sized span is first allocated from the central page heap.)</p>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">An object is returned to a central free list by adding it to the linked list of its containing span. If the linked list length now equals the total number of small objects in the span, this span is now completely free and is returned to the page heap.</p>
<h2 style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; font-family: Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Garbage Collection of Thread Caches</h2><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; display: inline !important; font: medium Simsun; white-space: normal; orphans: 2; float: none; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">A thread cache is garbage collected when the combined size of all objects in the cache exceeds 2MB. The garbage collection threshold is automatically decreased as the number of threads increases so that we don't waste an inordinate amount of memory in a program with lots of threads.</span> 
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">We walk over all free lists in the cache and move some number of objects from the free list to the corresponding central list.</p>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">The number of objects to be moved from a free list is determined using a per-list low-water-mark<span class="Apple-converted-space">&nbsp;</span><code>L</code>.<span class="Apple-converted-space">&nbsp;</span><code>L</code><span class="Apple-converted-space">&nbsp;</span>records the minimum length of the list since the last garbage collection. Note that we could have shortened the list by<span class="Apple-converted-space">&nbsp;</span><code>L</code><span class="Apple-converted-space">&nbsp;</span>objects at the last garbage collection without requiring any extra accesses to the central list. We use this past history as a predictor of future accesses and move<span class="Apple-converted-space">&nbsp;</span><code>L/2</code><span class="Apple-converted-space">&nbsp;</span>objects from the thread cache free list to the corresponding central free list. This algorithm has the nice property that if a thread stops using a particular size, all objects of that size will quickly move from the thread cache to the central free list where they can be used by other threads.</p>
<h2 style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; font-family: Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Performance Notes</h2>
<h3 style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; font-family: Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">PTMalloc2 unittest</h3><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; display: inline !important; font: medium Simsun; white-space: normal; orphans: 2; float: none; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">The PTMalloc2 package (now part of glibc) contains a unittest program t-test1.c. This forks a number of threads and performs a series of allocations and deallocations in each thread; the threads do not communicate other than by synchronization in the memory allocator.</span> 
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">t-test1 (included in google-perftools/tests/tcmalloc, and compiled as ptmalloc_unittest1) was run with a varying numbers of threads (1-20) and maximum allocation sizes (64 bytes - 32Kbytes). These tests were run on a 2.4GHz dual Xeon system with hyper-threading enabled, using Linux glibc-2.3.2 from RedHat 9, with one million operations per thread in each test. In each case, the test was run once normally, and once with LD_PRELOAD=libtcmalloc.so.</p>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">The graphs below show the performance of TCMalloc vs PTMalloc2 for several different metrics. Firstly, total operations (millions) per elapsed second vs max allocation size, for varying numbers of threads. The raw data used to generate these graphs (the output of the "time" utility) is available in t-test1.times.txt.</p>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">
<table>
<tbody>
<tr>
<td><img src="http://goog-perftools.sourceforge.net/doc/tcmalloc-opspersec.vs.size.1.threads.png"  alt="" /></td>
<td><img src="http://goog-perftools.sourceforge.net/doc/tcmalloc-opspersec.vs.size.2.threads.png"  alt="" /></td>
<td><img src="http://goog-perftools.sourceforge.net/doc/tcmalloc-opspersec.vs.size.3.threads.png"  alt="" /></td></tr>
<tr>
<td><img src="http://goog-perftools.sourceforge.net/doc/tcmalloc-opspersec.vs.size.4.threads.png"  alt="" /></td>
<td><img src="http://goog-perftools.sourceforge.net/doc/tcmalloc-opspersec.vs.size.5.threads.png"  alt="" /></td>
<td><img src="http://goog-perftools.sourceforge.net/doc/tcmalloc-opspersec.vs.size.8.threads.png"  alt="" /></td></tr>
<tr>
<td><img src="http://goog-perftools.sourceforge.net/doc/tcmalloc-opspersec.vs.size.12.threads.png"  alt="" /></td>
<td><img src="http://goog-perftools.sourceforge.net/doc/tcmalloc-opspersec.vs.size.16.threads.png"  alt="" /></td>
<td><img src="http://goog-perftools.sourceforge.net/doc/tcmalloc-opspersec.vs.size.20.threads.png"  alt="" /></td></tr></tbody></table></p>
<ul style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"><li>TCMalloc is much more consistently scalable than PTMalloc2 - for all thread counts &gt;1 it achieves ~7-9 million ops/sec for small allocations, falling to ~2 million ops/sec for larger allocations. The single-thread case is an obvious outlier, since it is only able to keep a single processor busy and hence can achieve fewer ops/sec. PTMalloc2 has a much higher variance on operations/sec - peaking somewhere around 4 million ops/sec for small allocations and falling to &lt;1 million ops/sec for larger allocations.</li><li>TCMalloc is faster than PTMalloc2 in the vast majority of cases, and particularly for small allocations. Contention between threads is less of a problem in TCMalloc.</li><li>TCMalloc's performance drops off as the allocation size increases. This is because the per-thread cache is garbage-collected when it hits a threshold (defaulting to 2MB). With larger allocation sizes, fewer objects can be stored in the cache before it is garbage-collected.</li><li>There is a noticeably drop in the TCMalloc performance at ~32K maximum allocation size; at larger sizes performance drops less quickly. This is due to the 32K maximum size of objects in the per-thread caches; for objects larger than this tcmalloc allocates from the central page heap.</li></ul>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Next, operations (millions) per second of CPU time vs number of threads, for max allocation size 64 bytes - 128 Kbytes.</p>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">
<table>
<tbody>
<tr>
<td><img src="http://goog-perftools.sourceforge.net/doc/tcmalloc-opspercpusec.vs.threads.64.bytes.png"  alt="" /></td>
<td><img src="http://goog-perftools.sourceforge.net/doc/tcmalloc-opspercpusec.vs.threads.256.bytes.png"  alt="" /></td>
<td><img src="http://goog-perftools.sourceforge.net/doc/tcmalloc-opspercpusec.vs.threads.1024.bytes.png"  alt="" /></td></tr>
<tr>
<td><img src="http://goog-perftools.sourceforge.net/doc/tcmalloc-opspercpusec.vs.threads.4096.bytes.png"  alt="" /></td>
<td><img src="http://goog-perftools.sourceforge.net/doc/tcmalloc-opspercpusec.vs.threads.8192.bytes.png"  alt="" /></td>
<td><img src="http://goog-perftools.sourceforge.net/doc/tcmalloc-opspercpusec.vs.threads.16384.bytes.png"  alt="" /></td></tr>
<tr>
<td><img src="http://goog-perftools.sourceforge.net/doc/tcmalloc-opspercpusec.vs.threads.32768.bytes.png"  alt="" /></td>
<td><img src="http://goog-perftools.sourceforge.net/doc/tcmalloc-opspercpusec.vs.threads.65536.bytes.png"  alt="" /></td>
<td><img src="http://goog-perftools.sourceforge.net/doc/tcmalloc-opspercpusec.vs.threads.131072.bytes.png"  alt="" /></td></tr></tbody></table></p>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Here we see again that TCMalloc is both more consistent and more efficient than PTMalloc2. For max allocation sizes &lt;32K, TCMalloc typically achieves ~2-2.5 million ops per second of CPU time with a large number of threads, whereas PTMalloc achieves generally 0.5-1 million ops per second of CPU time, with a lot of cases achieving much less than this figure. Above 32K max allocation size, TCMalloc drops to 1-1.5 million ops per second of CPU time, and PTMalloc drops almost to zero for large numbers of threads (i.e. with PTMalloc, lots of CPU time is being burned spinning waiting for locks in the heavily multi-threaded case).</p>
<h2 style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; letter-spacing: normal; font-family: Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Caveats</h2>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">For some systems, TCMalloc may not work correctly on with applications that aren't linked against libpthread.so (or the equivalent on your OS). It should work on Linux using glibc 2.3, but other OS/libc combinations have not been tested.</p>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">TCMalloc may be somewhat more memory hungry than other mallocs, though it tends not to have the huge blowups that can happen with other mallocs. In particular, at startup TCMalloc allocates approximately 6 MB of memory. It would be easy to roll a specialized version that trades a little bit of speed for more space efficiency.</p>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">TCMalloc currently does not return any memory to the system.</p>
<p style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; font: medium Simsun; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">Don't try to load TCMalloc into a running binary (e.g., using JNI in Java programs). The binary will have allocated some objects using the system malloc, and may try to pass them to TCMalloc for deallocation. TCMalloc will not be able to handle such objects.</p><img src ="http://www.cppblog.com/beautykingdom/aggbug/170077.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2012-04-04 21:15 <a href="http://www.cppblog.com/beautykingdom/archive/2012/04/04/170077.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>有抗癌效果的神奇食物</title><link>http://www.cppblog.com/beautykingdom/archive/2011/09/23/156586.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Fri, 23 Sep 2011 00:44:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2011/09/23/156586.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/156586.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2011/09/23/156586.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/156586.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/156586.html</trackback:ping><description><![CDATA[<h1 id="h1title">from:</h1>
<p><a href="http://health.msn.com.cn/healthcare/20110603/05001247621.shtml">http://health.msn.com.cn/healthcare/20110603/05001247621.shtml</a><br /></p><span class="info"><a href="http://health.msn.com.cn/" target="_blank"><font color="#333333">http://health.msn.com.cn</font></a> 2011-06-03 05:00:00 来源: 环球网健康频道 <img title="donghongbo" align="textTop" src="http://stimgcn1.s-msn.com/portal/health/content_v2/buffer.jpg"  alt="" /></span> 
<div class="endText">
<p align="center"><img src="http://health.msn.com.cn/2011/06/02/59de16cb-582f-4ef5-a681-38afda1409f0.jpg"  alt="" /><br /></p>
<p>　　保健：七种食物抗癌效果好</p>
<p>　　<strong>茄子</strong> &#8220;霜打茄子&#8221;是好药 。越来越多证据表明，茄子具有抗癌功能。曾有试验从茄子中提取的一种无毒物质，用于治疗胃癌、子宫颈癌等收到良效。</p>
<p>　　<strong>苦瓜</strong> 苦瓜是不可多得的抗癌瓜。苦瓜种子中含有一种蛋白酶抑制剂，能抑制肿瘤细胞分泌蛋白酶，从而抑制癌细胞的侵袭和转移。</p>
<p>　　<strong>海带</strong> 海带中药名为&#8220;昆布&#8221;，可预防乳腺癌和甲状腺肿瘤。海带可杀灭或抑制肠道内能够产生致癌物的细菌，所含的纤维还能促进胆汁酸和胆固醇的排出；海带提取物对各种癌细胞有直接抑制作用。</p>
<p>　　<strong>地瓜</strong> 地瓜是人们逐渐淡忘的抗癌佳品。别名甘薯、红薯、白薯，被认为是祛病延年、减肥保健的绝佳食品。其实地瓜能预防肠癌和乳腺癌的发生。</p>
<p>　　<strong>麦麸</strong> 麦麸是最好的防癌食物纤维，它能预防并治疗结直肠癌、糖尿并高胆固醇血症、高脂血症、便秘、痔疮等。</p>
<p>　　<strong>萝卜</strong> 萝卜是根茎类蔬菜中的&#8220;健康保护神&#8221;。胡萝卜因含丰富的胡萝卜素，也具有极好的防癌作用。</p>
<p>　　<strong>猕猴桃</strong> 猕猴桃维生素C含量居水果之冠，是名副其实的&#8220;天然维生素C片&#8221;，另外还含有丰富的具有保护血管功能的维生素P，其营养价值甚高。</p></div><img src ="http://www.cppblog.com/beautykingdom/aggbug/156586.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2011-09-23 08:44 <a href="http://www.cppblog.com/beautykingdom/archive/2011/09/23/156586.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ubuntu下编译内核</title><link>http://www.cppblog.com/beautykingdom/archive/2011/09/14/155714.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Tue, 13 Sep 2011 16:02:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2011/09/14/155714.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/155714.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2011/09/14/155714.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/155714.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/155714.html</trackback:ping><description><![CDATA[<div>先make menuconfig，选定cpu型号，要不会在install内核并重启的时候出现cpu unsupported之类的错。具体的命令为：<br /><span style="widows: 2; text-transform: none; background-color: rgb(250,250,250); text-indent: 0px; letter-spacing: normal; font: 12px/16px Monaco, 'Courier New', monospace; white-space: normal; orphans: 2; color: rgb(0,102,0); word-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="Apple-style-span">sudo make-kpkg&nbsp;--initrd --append-to-version=dell1400 kernel_image kernel-headers<br /><span style="widows: 2; text-transform: none; background-color: rgb(250,250,250); text-indent: 0px; letter-spacing: normal; font: 12px/16px Monaco, 'Courier New', monospace; white-space: normal; orphans: 2; color: rgb(0,102,0); word-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="Apple-style-span">sudo dpkg -i&nbsp; &nbsp;linux-image-*.deb<br /><br /><br />references:<br />1.<a href="http://forum.ubuntu.org.cn/viewtopic.php?t=134404">http://forum.ubuntu.org.cn/viewtopic.php?t=134404</a></span></span></div><img src ="http://www.cppblog.com/beautykingdom/aggbug/155714.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2011-09-14 00:02 <a href="http://www.cppblog.com/beautykingdom/archive/2011/09/14/155714.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MySQL索引背后的数据结构及算法原理</title><link>http://www.cppblog.com/beautykingdom/archive/2011/09/05/155112.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Mon, 05 Sep 2011 02:36:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2011/09/05/155112.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/155112.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2011/09/05/155112.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/155112.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/155112.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: from:http://www.cnblogs.com/leoo2sk/archive/2011/07/10/mysql-index.html#nav-2-2在编程领域有一句人尽皆知的法则&#8220;程序 = 数据结构 + 算法&#8221;，我个人是不太赞同这句话（因为我觉得程序不仅仅是数据结构加算法），但是在日常的学习和工作中我确认深深感受到数据结构和算法的重要性，很多东西，如果你愿意稍稍往...&nbsp;&nbsp;<a href='http://www.cppblog.com/beautykingdom/archive/2011/09/05/155112.html'>阅读全文</a><img src ="http://www.cppblog.com/beautykingdom/aggbug/155112.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2011-09-05 10:36 <a href="http://www.cppblog.com/beautykingdom/archive/2011/09/05/155112.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>wget进行整站下载&lt;转&gt;</title><link>http://www.cppblog.com/beautykingdom/archive/2011/08/21/154002.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Sun, 21 Aug 2011 01:56:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2011/08/21/154002.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/154002.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2011/08/21/154002.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/154002.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/154002.html</trackback:ping><description><![CDATA[from:<br /><a href="http://blog.chinaunix.net/space.php?uid=9950859&amp;do=blog&amp;id=2105109">http://blog.chinaunix.net/space.php?uid=9950859&amp;do=blog&amp;id=2105109</a><br /><br /><br /><span style="widows: 2; text-transform: none; background-color: rgb(242,247,247); text-indent: 0px; font: 14px/21px 宋体; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(10,20,20); word-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="Apple-style-span">get<font style="padding-bottom: 0px; line-height: 1.5; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: 宋体; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" color="#0000ff">&nbsp;-r -p -np -k</font>&nbsp;http://xxx.com/abc/<br style="padding-bottom: 0px; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: 宋体; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" /><br style="padding-bottom: 0px; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: 宋体; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" />-r,&nbsp; --recursive（递归）&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;specify recursive download.（指定递归下载）<br /><br style="padding-bottom: 0px; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: 宋体; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" />-k,&nbsp; --convert-links（转换链接）&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;make links in downloaded HTML point to local files.（将下载的HTML页面中的链接转换为相对链接即本地链接）<br style="padding-bottom: 0px; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: 宋体; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" /><br />-p,&nbsp; --page-requisites（页面必需元素）&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get all images, etc. needed to display HTML page.（下载所有的图片等页面显示所需的内容）<br style="padding-bottom: 0px; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: 宋体; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" /><br />-np, --no-parent（不追溯至父级）&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;don't ascend to the parent directory.<br style="padding-bottom: 0px; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: 宋体; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" /><br style="padding-bottom: 0px; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: 宋体; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" />另外断点续传用-nc参数 日志 用-o参数<br style="padding-bottom: 0px; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: 宋体; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" /></span><img src ="http://www.cppblog.com/beautykingdom/aggbug/154002.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2011-08-21 09:56 <a href="http://www.cppblog.com/beautykingdom/archive/2011/08/21/154002.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>What are the difference between DDL, DML and DCL commands?&lt;转载&gt;</title><link>http://www.cppblog.com/beautykingdom/archive/2011/08/19/153837.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Fri, 19 Aug 2011 02:26:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2011/08/19/153837.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/153837.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2011/08/19/153837.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/153837.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/153837.html</trackback:ping><description><![CDATA[<div>from:<br /><a href="http://www.orafaq.com/faq/what_are_the_difference_between_ddl_dml_and_dcl_commands">http://www.orafaq.com/faq/what_are_the_difference_between_ddl_dml_and_dcl_commands</a><br /><br /><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; border-collapse: separate; font: 16px 'Times New Roman'; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="Apple-style-span"><span style="text-align: left; line-height: 19px; border-collapse: collapse; font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51); font-size: 13px" class="Apple-style-span"> 
<h3 style="margin: 0px; font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(102,153,204); font-size: 1.5em"><a name="DDL">DDL</a></h3><br /><span style="font-weight: bold">Data Definition Language</span><span class="Apple-converted-space">&nbsp;</span>(DDL) statements are used to define the database structure or schema. Some examples: 
<p style="padding-bottom: 0px; margin: 0px 0px 1.2em; padding-left: 0px; padding-right: 0px; padding-top: 0px"></p>
<ul style="list-style-type: circle; font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)" class="bb-list"><li style="font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)">CREATE - to create objects in the database</li><li style="font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)">ALTER - alters the structure of the database</li><li style="font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)">DROP - delete objects from the database</li><li style="font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)">TRUNCATE - remove all records from a table, including all spaces allocated for the records are removed</li><li style="font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)">COMMENT - add comments to the data dictionary</li><li style="font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)">RENAME - rename an object</li></ul>
<p style="padding-bottom: 0px; margin: 0px 0px 1.2em; padding-left: 0px; padding-right: 0px; padding-top: 0px"></p>
<h3 style="margin: 0px; font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(102,153,204); font-size: 1.5em"><a name="DML">DML</a></h3><br /><span style="font-weight: bold">Data Manipulation Language</span><span class="Apple-converted-space">&nbsp;</span>(DML) statements are used for managing data within schema objects. Some examples: 
<p style="padding-bottom: 0px; margin: 0px 0px 1.2em; padding-left: 0px; padding-right: 0px; padding-top: 0px"></p>
<ul style="list-style-type: circle; font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)" class="bb-list"><li style="font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)">SELECT - retrieve data from the a database</li><li style="font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)">INSERT - insert data into a table</li><li style="font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)">UPDATE - updates existing data within a table</li><li style="font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)">DELETE - deletes all records from a table, the space for the records remain</li><li style="font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)">MERGE - UPSERT operation (insert or update)</li><li style="font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)">CALL - call a PL/SQL or Java subprogram</li><li style="font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)">EXPLAIN PLAN - explain access path to data</li><li style="font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)">LOCK TABLE - control concurrency</li></ul>
<p style="padding-bottom: 0px; margin: 0px 0px 1.2em; padding-left: 0px; padding-right: 0px; padding-top: 0px"></p>
<h3 style="margin: 0px; font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(102,153,204); font-size: 1.5em"><a name="DCL">DCL</a></h3><br /><span style="font-weight: bold">Data Control Language</span><span class="Apple-converted-space">&nbsp;</span>(DCL) statements. Some examples: 
<p style="padding-bottom: 0px; margin: 0px 0px 1.2em; padding-left: 0px; padding-right: 0px; padding-top: 0px"></p>
<ul style="list-style-type: circle; font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)" class="bb-list"><li style="font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)">GRANT - gives user's access privileges to database</li><li style="font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)">REVOKE - withdraw access privileges given with the GRANT command</li></ul>
<p style="padding-bottom: 0px; margin: 0px 0px 1.2em; padding-left: 0px; padding-right: 0px; padding-top: 0px"></p>
<h3 style="margin: 0px; font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(102,153,204); font-size: 1.5em"><a name="TCL">TCL</a></h3><br /><span style="font-weight: bold">Transaction Control</span><span class="Apple-converted-space">&nbsp;</span>(TCL) statements are used to manage the changes made by DML statements. It allows statements to be grouped together into logical transactions. 
<p style="padding-bottom: 0px; margin: 0px 0px 1.2em; padding-left: 0px; padding-right: 0px; padding-top: 0px"></p>
<ul style="list-style-type: circle; font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)" class="bb-list"><li style="font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)">COMMIT - save work done</li><li style="font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)">SAVEPOINT - identify a point in a transaction to which you can later roll back</li><li style="font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)">ROLLBACK - restore database to original since the last COMMIT</li><li style="font-family: 'Trebuchet MS', Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif; color: rgb(51,51,51)">SET TRANSACTION - Change transaction options like isolation level and what rollback segment to use</li></ul></span></span></div><img src ="http://www.cppblog.com/beautykingdom/aggbug/153837.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2011-08-19 10:26 <a href="http://www.cppblog.com/beautykingdom/archive/2011/08/19/153837.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>通过证书方式实现ssh的无密码登陆&lt;转&gt;</title><link>http://www.cppblog.com/beautykingdom/archive/2011/08/11/153065.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Thu, 11 Aug 2011 08:58:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2011/08/11/153065.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/153065.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2011/08/11/153065.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/153065.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/153065.html</trackback:ping><description><![CDATA[<p><font color="#000000" face="Verdana"><span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; border-collapse: separate; font: medium 'Times New Roman'; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="Apple-style-span"><span style="line-height: 15px; font-family: 宋体, Arial; font-size: 12px" class="Apple-style-span"></p>
<div style="padding-bottom: 0px; line-height: 1.5; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">相关文章很多，大同小异，本文只是为了按照那些文章配置，但是还是需要输入密码的情况写的。</div>
<div style="padding-bottom: 0px; line-height: 1.5; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">关键字：SSH证书方式登陆依然需要输入密码</div>
<div style="padding-bottom: 0px; line-height: 1.5; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">两台linux机器：A B</div>
<div style="padding-bottom: 0px; line-height: 1.5; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">都已经安装上OpenSSH,A上通过ssh-keygen生成一对密钥，</div>
<div style="padding-bottom: 0px; line-height: 1.5; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">公钥通过任意方式放到B的~/.ssh/authorized_keys文件里面。</div>
<div style="padding-bottom: 0px; line-height: 1.5; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">.ssh目录权限755，authorized_keys权限600。</div>
<div style="padding-bottom: 0px; line-height: 1.5; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">这时候在A上可以通过不用输入密码直接ssh B了。</div>
<div style="padding-bottom: 0px; line-height: 1.5; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">注意：很多文章说是authorized_keys的权限644，当你644的时候可能登陆的时候还会让你输入密码，但是一旦改成600以后并且成功登陆，这时候再改成644，此问题不再出现。</div>
<div style="padding-bottom: 0px; line-height: 1.5; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">被这个问题折腾了将近一个星期，郁闷是难免的了，甚至自己写了程序代替slogin scp等命令，最终还是配置成功了。</div>
<p></span></span><br class="Apple-interchange-newline" />from:<br /><a href="http://blog.chinaunix.net/space.php?uid=233938&amp;do=blog&amp;cuid=211941">http://blog.chinaunix.net/space.php?uid=233938&amp;do=blog&amp;cuid=211941</a><br /></font></p><img src ="http://www.cppblog.com/beautykingdom/aggbug/153065.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2011-08-11 16:58 <a href="http://www.cppblog.com/beautykingdom/archive/2011/08/11/153065.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>50个有关编程的至理名言&lt;转&gt;</title><link>http://www.cppblog.com/beautykingdom/archive/2011/06/11/148476.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Fri, 10 Jun 2011 16:07:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2011/06/11/148476.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/148476.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2011/06/11/148476.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/148476.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/148476.html</trackback:ping><description><![CDATA[<span style="widows: 2; text-transform: none; text-indent: 0px; border-collapse: separate; font: 12px/18px Verdana, Arial, Helvetica, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(73,73,73); word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="Apple-style-span"><span style="line-height: 25px; color: rgb(64,64,64); font-size: 14px" class="Apple-style-span"> 
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">程序员世界里有哪些名言警局呢？Jun Auza 列出了50条启迪人心的至理名言，它们大多来自产业界富于经验的人们。下文列出前10个供读者欣赏。</p>
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">　　10. "People think that computer science is the art of geniuses but the actual reality is the opposite, just many people doing things that build on each other, like a wall of mini stones."- Donald Knuth</p>
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">　　10. &#8220;人们认为计算机科学是天才的艺术，但事实完全相反：只是很多人在共同建立起来的事物之上工作，就像一条由小石头铺成的小径。&#8221;&#8212;&#8212; Donald Knuth</p>
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">　　9. &#8220;First learn computer science and all the theory. Next develop a programming style. Then forget all that and just hack.&#8221;- George Carrette</p>
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">　　9. &#8220;首先学会计算机科学和所有的理论。然后发展出一个编程风格。之后便要忘掉所有这些，以自由的方式探索。&#8221;&#8212;&#8212; George Carrette</p>
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">　　8. &#8220;Most of you are familiar with the virtues of a programmer. There are three, of course: laziness, impatience, and hubris.&#8221;- Larry Wall</p>
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">　　8. &#8220;大多数的你们都熟悉程序员的美德。它们有三点：懒，不耐烦，以及狂妄自大。&#8221;&#8212;&#8212; Larry Wall</p>
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">　　7. &#8220;Most software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other,with no structural integrity， but just done by brute force and thousands of slaves.&#8221;- Alan Kay</p>
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">　　7. &#8220;今日的大多数软件很像埃及金字塔，由千百万砖头堆砌起来，层层相切，没有着整体的结构，是由畜力和成千上万奴隶的力量建立起来的。&#8221;&#8212;&#8212; Alan Kay</p>
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">　　6. &#8220;The trouble with programmers is that you can never tell what a programmer is doing until it&#8217;s too late.&#8221;- Seymour Cray</p>
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">　　6. &#8220;程序员的问题是，不到太晚，你永远无法知道一个他在做着些什么。&#8221;&#8212;&#8212; Seymour Cray</p>
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">　　5. &#8220;To iterate is human, to recurse divine.&#8221;- L. Peter Deutsch</p>
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">　　5. &#8220;人理解迭代，神理解递归。&#8221;&#8212;&#8212; Peter Deutsch</p>
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">　　4. "On two occasions I have been asked [by members of Parliament]: 'Pray， Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."- Charles Babbage</p>
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">　　4. &#8220;有两次我被（国会议员）问道：&#8216; Mr. Babbage，如果你输入计算机错误的数据，正确的答案会出来吗？&#8217;我完全无法理解能产生此种问题的大脑的混乱。&#8221;</p>
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">　　3. "Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program."- Linus Torvalds</p>
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">　　3. &#8220;大部分好的程序员编程并不是为了钱或名望，而只是因为纯粹的乐趣。&#8221;&#8212;&#8212; Linus Torvalds</p>
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">　　2. "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live."- Martin Golding</p>
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">　　2. &#8220;编程的时候，总是想着那个维护你代码的人会是一个知道你住在哪儿的有暴力倾向的精神病患者。&#8221;&#8212;&#8212; Martin Golding</p>
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">　　1. &#8220;There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies.&#8221;- C.A.R. Hoare</p>
<p style="padding-bottom: 0px; line-height: 25px; margin: 10px 0px; padding-left: 0px; padding-right: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; color: rgb(64,64,64); font-size: 14px; padding-top: 0px">　　1. &#8220;有两种生成一个软件设计方案的途径。一个是把它做得如此简单，以致于明显不会有漏洞存在。另一个是把它做的如此复杂，以致于不会有明显的漏洞存在。&#8221;&#8212;&#8212; C.A.R. Hoare<br /><br />from:<br /><a href="http://news.cnblogs.com/n/84721/">http://news.cnblogs.com/n/84721/</a><br /></p></span></span><img src ="http://www.cppblog.com/beautykingdom/aggbug/148476.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2011-06-11 00:07 <a href="http://www.cppblog.com/beautykingdom/archive/2011/06/11/148476.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>How I explained Design Patterns to my wife《reprint》</title><link>http://www.cppblog.com/beautykingdom/archive/2011/06/08/148264.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Wed, 08 Jun 2011 06:14:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2011/06/08/148264.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/148264.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2011/06/08/148264.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/148264.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/148264.html</trackback:ping><description><![CDATA[<span style="widows: 2; text-transform: none; text-indent: 0px; letter-spacing: normal; border-collapse: separate; font: 16px 'Times New Roman'; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="Apple-style-span"><span style="line-height: 16px; font-family: Verdana, Arial, sans-serif; font-size: 13px" class="Apple-style-span"> 
<h2 style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; color: rgb(255,153,0); font-size: 13pt; font-weight: bold">Introduction</h2>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">Me and my wife had some interesting conversations on<span class="Apple-converted-space">&nbsp;</span><a style="color: rgb(0,76,213); text-decoration: none" href="http://www.codeproject.com/KB/architecture/SOLIDPrinciplesInOOD.aspx">Object Oriented Design principles</a>. After publishing the conversation on CodeProject, I got some good responses from the community and that really inspired me. So, I am happy to share our next conversation that took place on Object Oriented Design Patterns. Here it is.</p>
<h2 style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; color: rgb(255,153,0); font-size: 13pt; font-weight: bold">What is a Design Pattern?</h2>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: I guess you already have some basic idea about Object Oriented Design principles. We had a nice talk on the OOD principles (SOLID principles), and I hope you didn't mind that I published our conversation in a CodeProject article. You can find it here:<span class="Apple-converted-space">&nbsp;</span><a style="color: rgb(0,76,213); text-decoration: none" href="http://www.codeproject.com/KB/architecture/SOLIDPrinciplesInOOD.aspx">How I explained OOD to my wife</a>.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">Design Patterns are nothing but applications of those principles in some specific and common situations, and standardizing some of those. Let's try to understand what Design Patterns are by using some examples.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: Sure, I love examples.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: Let's talk about our car. It's an object, though a complex one, which consists of thousands of other objects such as the engine, wheels, steering, seats, body, and thousands of different parts and machinery.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><img style="overflow-x: auto; overflow-y: auto" src="http://www.codeproject.com/KB/architecture/LearningDesignPatterns1/Engine.jpg" width="150" height="150" complete="true"  alt="" /><img style="overflow-x: auto; overflow-y: auto" src="http://www.codeproject.com/KB/architecture/LearningDesignPatterns1/Wheel.jpg" width="150" height="99" complete="true"  alt="" /><img style="overflow-x: auto; overflow-y: auto" src="http://www.codeproject.com/KB/architecture/LearningDesignPatterns1/Parts.jpg" width="150" height="112" complete="true"  alt="" /><img style="overflow-x: auto; overflow-y: auto" src="http://www.codeproject.com/KB/architecture/LearningDesignPatterns1/lights.jpg" width="98" height="150" complete="true"  alt="" /><img style="overflow-x: auto; overflow-y: auto" src="http://www.codeproject.com/KB/architecture/LearningDesignPatterns1/steering.jpg" width="150" height="93" complete="true"  alt="" /></p>
<div style="font-style: italic; font-size: 8pt; font-weight: bold" class="Caption">Different parts of a car.</div>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">While building this car, the manufacturer gathered and assembled all the different smaller parts that are subsystems of the car. These different smaller parts are also some complex objects, and some other manufacturers had to build and assemble those too. But, while building the car, the car company doesn't really bother too much about how those objects were built and assembled (well, as long as they are sure about the quality of these smaller objects/equipments). Rather, the car manufacturer cares about how to assemble those different objects into different combinations and produce different models of cars.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><img style="overflow-x: auto; overflow-y: auto" src="http://www.codeproject.com/KB/architecture/LearningDesignPatterns1/car1.jpg" width="150" height="74" complete="true"  alt="" /><img style="overflow-x: auto; overflow-y: auto" src="http://www.codeproject.com/KB/architecture/LearningDesignPatterns1/car2.jpg" width="150" height="78" complete="true"  alt="" /><img style="overflow-x: auto; overflow-y: auto" src="http://www.codeproject.com/KB/architecture/LearningDesignPatterns1/car3.jpg" width="150" height="98" complete="true"  alt="" /></p>
<div style="font-style: italic; font-size: 8pt; font-weight: bold" class="Caption">Different models of cars, produced by assembling different parts and following different designs.</div>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: The car manufacturer company must have some designs or blue prints for each different model of car which they follow, right?</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: Definitely, and, these designs are well-thought designs, and they've put a good amount of time and effort to sketch those designs. Once the designs are finalized, producing a car is just a matter of following the designs.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: Hm.. it's good to have some good designs upfront and following those allows to produce different products in a quick amount of time, and each time the manufacturer has to build a product for a specific model, they don't have to develop a design from scratch or re-invent the wheel, they just follow the designs.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><img style="overflow-x: auto; overflow-y: auto" src="http://www.codeproject.com/KB/architecture/LearningDesignPatterns1/plan1.jpg" width="249" height="149" complete="true"  alt="" /><img style="overflow-x: auto; overflow-y: auto" src="http://www.codeproject.com/KB/architecture/LearningDesignPatterns1/plan2.jpg" width="286" height="176" complete="true"  alt="" /></p>
<div style="font-style: italic; font-size: 8pt; font-weight: bold" class="Caption">Different design plans for producing different models of products (cars).</div>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: You got the point. Now, we are software manufacturers and we build different kinds of software programs with different components or functionality based upon the requirements. While building such different software systems, we often have to develop code for some situations that are common in many different software systems, right?</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: Yes. And often, we face common design problems while developing different software applications.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: We try to develop our software applications in an Object Oriented manner and try to apply OOD principles for achieving code that is manageable, reusable, and expandable. Wouldn't it be nice whenever we see such design problems, we have a pool of some carefully made and well tested designs of objects for solving those?</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: Yes, that would save us time and would also allow us to build better software systems and manage them later.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: Perfect. The good news is, you don't have to really develop that pool of object designs from scratch. People already have gone through similar design problems for years, and they already have identified some good design solutions which have been standardized already. We call these Design Patterns.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">We must thank the Gang of Four (GoF) for identifying the 23 basic Design Patterns in their book<span class="Apple-converted-space">&nbsp;</span><strong>Design Patterns: Elements of Reusable Object-Oriented Software</strong>. In case you are wondering who formed this famous gang, they are Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. There are many Object Oriented Design Patterns, but these 23 patterns are generally considered the foundation for all other Design Patterns.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: Can I create a new pattern? Is that possible?</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: Yes darling, why not? Design Patterns are not something invented or newly created by scientists. They are just discovered. That means, for each kind of common problem scenario, there must be some good design solutions there. If we are able to identify an object oriented design that could solve a new design related problem, that would be a new Design Pattern defined by us. Who knows? If we discover some a Design Pattern, someday people may call us Gang of Two.. Ha ha.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Fahana</strong>: :)</p>
<h2 style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; color: rgb(255,153,0); font-size: 13pt; font-weight: bold">How will we learn Design Patterns?</h2>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: As I have always believed, examples are the greatest way of learning. In our learning approach, we won't discuss the theories first and implement later. I think this is a BAD approach. Design Patterns were not invented based on theories. Rather, the problem situations occurred first and based upon the requirement and context, some design solutions were evolved, and later some of them were standardized as patterns. So, for each design pattern we discuss, we will try to understand and analyze some real life example problems, and then we will try to formulate a design in a step by step process and end up with a design that will match with some patterns; Design Patterns were discovered in this same process. What do you think?</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: I think this approach makes more sense to me. If I can end up with Design Patterns by analyzing problems and formulating solutions, I won't have to memorize design diagrams and definitions. Please proceed using your approach.</p>
<h2 style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; color: rgb(255,153,0); font-size: 13pt; font-weight: bold">A basic design problem and its solution</h2>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: Let's consider the following scenario:</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">Our room has some electric equipments (lights, fans etc). The equipments are arranged in a way where they could be controlled by switches. At any time, you can replace or troubleshoot an electrical equipment without touching the other things. For example, you can replace a light with another without replacing or changing the switch. Also, you can replace a switch or troubleshoot it without touching or changing the corresponding light or fan; you can even connect the light with the fan's switch and connect the fan with the light's switch, without touching the switches.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><img style="overflow-x: auto; overflow-y: auto" src="http://www.codeproject.com/KB/architecture/LearningDesignPatterns1/fan.jpg" width="258" height="196" complete="true"  alt="" /><img style="overflow-x: auto; overflow-y: auto" src="http://www.codeproject.com/KB/architecture/LearningDesignPatterns1/light.jpg" width="129" height="215" complete="true"  alt="" /></p>
<div style="font-style: italic; font-size: 8pt; font-weight: bold" class="Caption">Electrical equipments: A fan and a light.</div>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><img style="overflow-x: auto; overflow-y: auto" src="http://www.codeproject.com/KB/architecture/LearningDesignPatterns1/normalswitch.jpg" width="186" height="191" complete="true"  alt="" /><img style="overflow-x: auto; overflow-y: auto" src="http://www.codeproject.com/KB/architecture/LearningDesignPatterns1/fancyswitch.jpg" width="155" height="147" complete="true"  alt="" /></p>
<div style="font-style: italic; font-size: 8pt; font-weight: bold" class="Caption">Two different switches for fan and light, one is normal and the other is fancy.</div>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: Yes, but that's natural, right?</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: Yes, that's very natural, and that's how the arrangement should be. When different things are connected together, they should be connected in a way where change or replacement of one system doesn't affect another, or even if there is any effect, it stays minimal. This allows you to manage your system easily and at low cost. Just imagine if changing the light in your room requires you to change the switch also. Would you care to purchase and set up such a system in your house?</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: Definitely no.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: Now, let's think how the lights or fans are connected with the switches so that changing one doesn't have any impact on the other. What do you think?</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: The wire, of course!</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: Perfect. It's the wire and the electrical arrangement that connect the lights/fans with the switches. We can generalize it as a bridge between the different systems that can get connected through it. The basic idea is, things shouldn't be directly connected with one another. Rather, they should be connected though some bridges or interfaces. That's what we call "loose coupling" in software world.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: I see. I got the idea.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: Now, let's try to understand some key issues in the light/fan and switch analogy, and try to understand how they are designed and connected.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: OK, let me try.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">We have switches in our example. There may be some specific kinds of switches like normal switches, fancy ones, but, in general, they are switches. And, each switch can be turned on and off.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">So, we will have a base<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">Switch</code><span class="Apple-converted-space">&nbsp;</span>class as follows:</p>
<div style="text-align: right !important; display: block; font-size: 8pt !important" id="premain0" class="small-text align-right" width="100%"><img style="overflow-x: auto; overflow-y: auto; cursor: pointer" id="preimg0" src="http://www.codeproject.com/images/minus.gif" width="9" height="9" preid="0"  alt="" /><span style="margin-bottom: 0px; cursor: pointer" id="precollapse0" preid="0"><span class="Apple-converted-space">&nbsp;</span>Collapse</span></div><pre style="border-bottom: rgb(251,237,187) 1px solid; border-left: rgb(251,237,187) 1px solid; padding-bottom: 6px; overflow-x: auto; overflow-y: auto; background-color: rgb(251,237,187); margin-top: 0px; padding-left: 6px; padding-right: 6px; font: 9pt 'Courier New', Courier, mono; word-wrap: break-word; white-space: pre-wrap; border-top: rgb(251,237,187) 1px solid; border-right: rgb(251,237,187) 1px solid; padding-top: 6px" id="pre0" lang="cs"><span style="color: blue" class="code-keyword">public</span> <span style="color: blue" class="code-keyword">class</span> Switch
{
  <span style="color: blue" class="code-keyword">public</span> <span style="color: blue" class="code-keyword">void</span> On()
  { 
    <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">Switch has an on button
</span>  }
  <span style="color: blue" class="code-keyword">public</span> <span style="color: blue" class="code-keyword">void</span> Off()
  {
    <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">Switch has an off button
</span>  }
}</pre>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">And, as we may have some specific kinds of switches, for example a fancy switch, a normal switch etc., we will also have<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">FancySwitch</code><span class="Apple-converted-space">&nbsp;</span>and<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">NormalSwitch</code><span class="Apple-converted-space">&nbsp;</span>classes extending the<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">Switch</code><span class="Apple-converted-space">&nbsp;</span>class:</p>
<div style="text-align: right !important; display: block; font-size: 8pt !important" id="premain1" class="small-text align-right" width="100%"><img style="overflow-x: auto; overflow-y: auto; cursor: pointer" id="preimg1" src="http://www.codeproject.com/images/minus.gif" width="9" height="9" preid="1"  alt="" /><span style="margin-bottom: 0px; cursor: pointer" id="precollapse1" preid="1"><span class="Apple-converted-space">&nbsp;</span>Collapse</span></div><pre style="border-bottom: rgb(251,237,187) 1px solid; border-left: rgb(251,237,187) 1px solid; padding-bottom: 6px; overflow-x: auto; overflow-y: auto; background-color: rgb(251,237,187); margin-top: 0px; padding-left: 6px; padding-right: 6px; font: 9pt 'Courier New', Courier, mono; word-wrap: break-word; white-space: pre-wrap; border-top: rgb(251,237,187) 1px solid; border-right: rgb(251,237,187) 1px solid; padding-top: 6px" id="pre1" lang="cs"><span style="color: blue" class="code-keyword">public</span> <span style="color: blue" class="code-keyword">class</span> NormalSwitch : Switch
{
}

<span style="color: blue" class="code-keyword">public</span> <span style="color: blue" class="code-keyword">class</span> FancySwitch : Switch
{
}</pre>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">These two specific switch classes may have their own specific features and behaviours, but for now, let's keep them simple.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: Cool. Now, what about fan and light?</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: Let me try. I learned from the Open Closed principles from Object Oriented Design principles that we should try to do abstractions whenever possible, right?</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: Right.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: Unlike switches, fan and light are two different things. For switches, we were able to use a base<code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">Switch</code><span class="Apple-converted-space">&nbsp;</span>class, but as fan and light are two different things, instead of defining a base class, an interface might be more appropriate. In general, they are all electrical equipments. So, we can define an interface, say,<code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">IElectricalEquipment</code>, for abstracting fans and lights, right?</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: Right.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: OK, each electrical equipment has some common functionality. They could all be turned on or off. So the interface may be as follows:</p>
<div style="text-align: right !important; display: block; font-size: 8pt !important" id="premain2" class="small-text align-right" width="100%"><img style="overflow-x: auto; overflow-y: auto; cursor: pointer" id="preimg2" src="http://www.codeproject.com/images/minus.gif" width="9" height="9" preid="2"  alt="" /><span style="margin-bottom: 0px; cursor: pointer" id="precollapse2" preid="2"><span class="Apple-converted-space">&nbsp;</span>Collapse</span></div><pre style="border-bottom: rgb(251,237,187) 1px solid; border-left: rgb(251,237,187) 1px solid; padding-bottom: 6px; overflow-x: auto; overflow-y: auto; background-color: rgb(251,237,187); margin-top: 0px; padding-left: 6px; padding-right: 6px; font: 9pt 'Courier New', Courier, mono; word-wrap: break-word; white-space: pre-wrap; border-top: rgb(251,237,187) 1px solid; border-right: rgb(251,237,187) 1px solid; padding-top: 6px" id="pre2" lang="cs"><span style="color: blue" class="code-keyword">public</span> <span style="color: blue" class="code-keyword">interface</span> IElectricalEquipment
{
    <span style="color: blue" class="code-keyword">void</span> PowerOn(); <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">Each electrical equipment can be turned on
</span>    <span style="color: blue" class="code-keyword">void</span> PowerOff(); <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">Each electrical equipment can be turned off
</span>}</pre>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: Great. You are getting good at abstracting things. Now, we need a bridge. In real world, the wires are the bridges. But, in our object design, a switch knows how to turn on or off an electrical equipment, and the electrical equipment somehow needs to be connected with the switches, As we don't have any wire here, the only way to let the electrical equipment be connected with the switch is encapsulation.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: Yes, but switches don't know the fans or lights directly. A switch actually knows about an electrical equipment<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">IElectricalEquipment</code><span class="Apple-converted-space">&nbsp;</span>that it can turn on or off. So, that means, an<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">ISwitch</code><span class="Apple-converted-space">&nbsp;</span>should have an<code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">IElectricalEquipment</code><span class="Apple-converted-space">&nbsp;</span>instance, right?</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: Right. Here, the encapsulated instance, which is an abstraction of fan or light (<code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">IElectricalEquipment</code>) is the bridge. So, let's modify the<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">Switch</code><span class="Apple-converted-space">&nbsp;</span>class to encapsulate an electrical equipment:</p>
<div style="text-align: right !important; display: block; font-size: 8pt !important" id="premain3" class="small-text align-right" width="100%"><img style="overflow-x: auto; overflow-y: auto; cursor: pointer" id="preimg3" src="http://www.codeproject.com/images/minus.gif" width="9" height="9" preid="3"  alt="" /><span style="margin-bottom: 0px; cursor: pointer" id="precollapse3" preid="3"><span class="Apple-converted-space">&nbsp;</span>Collapse</span></div><pre style="border-bottom: rgb(251,237,187) 1px solid; border-left: rgb(251,237,187) 1px solid; padding-bottom: 6px; overflow-x: auto; overflow-y: auto; background-color: rgb(251,237,187); margin-top: 0px; padding-left: 6px; padding-right: 6px; font: 9pt 'Courier New', Courier, mono; word-wrap: break-word; white-space: pre-wrap; border-top: rgb(251,237,187) 1px solid; border-right: rgb(251,237,187) 1px solid; padding-top: 6px" id="pre3" lang="cs"><span style="color: blue" class="code-keyword">public</span> <span style="color: blue" class="code-keyword">class</span> Switch
{
  <span style="color: blue" class="code-keyword">public</span> IElectricalEquipment equipment
  {
    <span style="color: blue" class="code-keyword">get</span>;
    <span style="color: blue" class="code-keyword">set</span>;
  }
  <span style="color: blue" class="code-keyword">public</span> <span style="color: blue" class="code-keyword">void</span> On()
  {
    <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">Switch has an on button
</span>  }
  <span style="color: blue" class="code-keyword">public</span> <span style="color: blue" class="code-keyword">void</span> Off()
  {
    <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">Switch has an off button
</span>  }
}</pre>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: Understood. Let me try to define the actual electrical equipments, the fan and the light. As I see, these are electrical equipments in general, so these would simply implement the<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">IElectricalEquipment</code>interface.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">Following is the<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">Fan</code><span class="Apple-converted-space">&nbsp;</span>class:</p>
<div style="text-align: right !important; display: block; font-size: 8pt !important" id="premain4" class="small-text align-right" width="100%"><img style="overflow-x: auto; overflow-y: auto; cursor: pointer" id="preimg4" src="http://www.codeproject.com/images/minus.gif" width="9" height="9" preid="4"  alt="" /><span style="margin-bottom: 0px; cursor: pointer" id="precollapse4" preid="4"><span class="Apple-converted-space">&nbsp;</span>Collapse</span></div><pre style="border-bottom: rgb(251,237,187) 1px solid; border-left: rgb(251,237,187) 1px solid; padding-bottom: 6px; overflow-x: auto; overflow-y: auto; background-color: rgb(251,237,187); margin-top: 0px; padding-left: 6px; padding-right: 6px; font: 9pt 'Courier New', Courier, mono; word-wrap: break-word; white-space: pre-wrap; border-top: rgb(251,237,187) 1px solid; border-right: rgb(251,237,187) 1px solid; padding-top: 6px" id="pre4" lang="cs"><span style="color: blue" class="code-keyword">public</span> <span style="color: blue" class="code-keyword">class</span> Fan : IElectricalEquipment
{
  <span style="color: blue" class="code-keyword">public</span> <span style="color: blue" class="code-keyword">void</span> PowerOn()
  {
    Console.WriteLine(<span style="color: purple" class="code-string">"</span><span style="color: purple" class="code-string">Fan is on"</span>);
  }
  <span style="color: blue" class="code-keyword">public</span> <span style="color: blue" class="code-keyword">void</span> PowerOff()
  {
    Console.WriteLine(<span style="color: purple" class="code-string">"</span><span style="color: purple" class="code-string">Fan is off"</span>);
  }
}</pre>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">And, the<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">Fan</code><span class="Apple-converted-space">&nbsp;</span>class would be as follows:</p>
<div style="text-align: right !important; display: block; font-size: 8pt !important" id="premain5" class="small-text align-right" width="100%"><img style="overflow-x: auto; overflow-y: auto; cursor: pointer" id="preimg5" src="http://www.codeproject.com/images/minus.gif" width="9" height="9" preid="5"  alt="" /><span style="margin-bottom: 0px; cursor: pointer" id="precollapse5" preid="5"><span class="Apple-converted-space">&nbsp;</span>Collapse</span></div><pre style="border-bottom: rgb(251,237,187) 1px solid; border-left: rgb(251,237,187) 1px solid; padding-bottom: 6px; overflow-x: auto; overflow-y: auto; background-color: rgb(251,237,187); margin-top: 0px; padding-left: 6px; padding-right: 6px; font: 9pt 'Courier New', Courier, mono; word-wrap: break-word; white-space: pre-wrap; border-top: rgb(251,237,187) 1px solid; border-right: rgb(251,237,187) 1px solid; padding-top: 6px" id="pre5" lang="cs"><span style="color: blue" class="code-keyword">public</span> <span style="color: blue" class="code-keyword">class</span> Light : IElectricalEquipment
{
  <span style="color: blue" class="code-keyword">public</span> <span style="color: blue" class="code-keyword">void</span> PowerOn()
  {    
    Console.WriteLine(<span style="color: purple" class="code-string">"</span><span style="color: purple" class="code-string">Light is on"</span>);
  }
  <span style="color: blue" class="code-keyword">public</span> <span style="color: blue" class="code-keyword">void</span> PowerOff()
  {
    Console.WriteLine(<span style="color: purple" class="code-string">"</span><span style="color: purple" class="code-string">Light is off"</span>);
  }
}</pre>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: Great. Now, let's make switches work. The switches should have the ability inside them to turn on and turn off the electrical equipment (it is connected to) when the switch is turned on and off.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">These are the key issues:</p>
<ul><li style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">When the<span class="Apple-converted-space">&nbsp;</span><em>On</em><span class="Apple-converted-space">&nbsp;</span>button is pressed on the switch, the electrical equipment connected to it should be turned on.</li><li style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">When the<span class="Apple-converted-space">&nbsp;</span><em>Off</em><span class="Apple-converted-space">&nbsp;</span>button is pressed on the switch, the electrical equipment connected to it should be turned off.</li></ul>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">Basically, following is what we want to achieve:</p>
<div style="text-align: right !important; display: block; font-size: 8pt !important" id="premain6" class="small-text align-right" width="100%"><img style="overflow-x: auto; overflow-y: auto; cursor: pointer" id="preimg6" src="http://www.codeproject.com/images/minus.gif" width="9" height="9" preid="6"  alt="" /><span style="margin-bottom: 0px; cursor: pointer" id="precollapse6" preid="6"><span class="Apple-converted-space">&nbsp;</span>Collapse</span></div><pre style="border-bottom: rgb(251,237,187) 1px solid; border-left: rgb(251,237,187) 1px solid; padding-bottom: 6px; overflow-x: auto; overflow-y: auto; background-color: rgb(251,237,187); margin-top: 0px; padding-left: 6px; padding-right: 6px; font: 9pt 'Courier New', Courier, mono; word-wrap: break-word; white-space: pre-wrap; border-top: rgb(251,237,187) 1px solid; border-right: rgb(251,237,187) 1px solid; padding-top: 6px" id="pre6" lang="cs"><span style="color: blue" class="code-keyword">static</span> <span style="color: blue" class="code-keyword">void</span> Main(<span style="color: blue" class="code-keyword">string</span>[] args)
{
  <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">We have some electrical equipments, say Fan, Light etc.
</span>  <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">So, lets create them first.
</span>
  IElectricalEquipment fan = <span style="color: blue" class="code-keyword">new</span> Fan();
  IElectricalEquipment light = <span style="color: blue" class="code-keyword">new</span> Light();

  <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">We also have some switches. Lets create them too.
</span>
  Switch fancySwitch = <span style="color: blue" class="code-keyword">new</span> FancySwitch();
  Switch normalSwitch = <span style="color: blue" class="code-keyword">new</span> NormalSwitch();

  <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">Lets connect the Fan to the fancy switch
</span>
  fancySwitch.equipment = fan;

  <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">As the switch now has an equipment (Fan),
</span>  <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">so switching on or off should 
</span>  <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">turn on or off the electrical equipment  
</span>
  fancySwitch.On(); <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">It should turn on the Fan. 
</span>
  <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">so, inside the On() method of Switch,  
</span>  <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">we must turn on the electrical equipment.
</span>    
  <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">It should turn off the Fan. So, inside the On() method of  
</span>  fancySwitch.Off();
  <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">Switch, we must turn off the electrical equipment
</span>
  <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">Now, lets plug the light to the fancy switch
</span>
  fancySwitch.equipment = light;
  fancySwitch.On(); <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">It should turn on the Light now
</span>  fancySwitch.Off(); <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">It should be turn off the Light now
</span>}</pre>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: I got it. So, the<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">On()</code><span class="Apple-converted-space">&nbsp;</span>method of the actual switches should internally call the<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">TurnOn()</code><span class="Apple-converted-space">&nbsp;</span>method of the electrical equipment, and the<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">Off()</code><span class="Apple-converted-space">&nbsp;</span>should call the<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">TurnOff()</code><span class="Apple-converted-space">&nbsp;</span>method on the equipment. So, the<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">Switch</code>class should be as follows:</p>
<div style="text-align: right !important; display: block; font-size: 8pt !important" id="premain7" class="small-text align-right" width="100%"><img style="overflow-x: auto; overflow-y: auto; cursor: pointer" id="preimg7" src="http://www.codeproject.com/images/minus.gif" width="9" height="9" preid="7"  alt="" /><span style="margin-bottom: 0px; cursor: pointer" id="precollapse7" preid="7"><span class="Apple-converted-space">&nbsp;</span>Collapse</span></div><pre style="border-bottom: rgb(251,237,187) 1px solid; border-left: rgb(251,237,187) 1px solid; padding-bottom: 6px; overflow-x: auto; overflow-y: auto; background-color: rgb(251,237,187); margin-top: 0px; padding-left: 6px; padding-right: 6px; font: 9pt 'Courier New', Courier, mono; word-wrap: break-word; white-space: pre-wrap; border-top: rgb(251,237,187) 1px solid; border-right: rgb(251,237,187) 1px solid; padding-top: 6px" id="pre7" lang="cs"><span style="color: blue" class="code-keyword">public</span> <span style="color: blue" class="code-keyword">class</span> Switch
{
  <span style="color: blue" class="code-keyword">public</span> <span style="color: blue" class="code-keyword">void</span> On()
  {
    Console.WriteLine(<span style="color: purple" class="code-string">"</span><span style="color: purple" class="code-string">Switch on the equipment"</span>);
    equipment.PowerOn();
  }
  <span style="color: blue" class="code-keyword">public</span> <span style="color: blue" class="code-keyword">void</span> Off()
  {
    Console.WriteLine(<span style="color: purple" class="code-string">"</span><span style="color: purple" class="code-string">Switch off the equipment"</span>);
    equipment.PowerOff();
  }
}</pre>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: Great work. Now, this certainly allows you to plug a fan from one switch to another. But you see, the opposite should also work. That means, you can change the switch of a fan or light without touching the fan or light. For example, you can easily change the switch of the light from<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">FancySwitch</code><span class="Apple-converted-space">&nbsp;</span>to<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">NormalSwitch</code><span class="Apple-converted-space">&nbsp;</span>as follows:</p>
<div style="text-align: right !important; display: block; font-size: 8pt !important" id="premain8" class="small-text align-right" width="100%"><img style="overflow-x: auto; overflow-y: auto; cursor: pointer" id="preimg8" src="http://www.codeproject.com/images/minus.gif" width="9" height="9" preid="8"  alt="" /><span style="margin-bottom: 0px; cursor: pointer" id="precollapse8" preid="8"><span class="Apple-converted-space">&nbsp;</span>Collapse</span></div><pre style="border-bottom: rgb(251,237,187) 1px solid; border-left: rgb(251,237,187) 1px solid; padding-bottom: 6px; overflow-x: auto; overflow-y: auto; background-color: rgb(251,237,187); margin-top: 0px; padding-left: 6px; padding-right: 6px; font: 9pt 'Courier New', Courier, mono; word-wrap: break-word; white-space: pre-wrap; border-top: rgb(251,237,187) 1px solid; border-right: rgb(251,237,187) 1px solid; padding-top: 6px" id="pre8" lang="cs">normalSwitch .equipment = light;
normalSwitch.On(); <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">It should turn on the Light now
</span>normalSwitch.Off(); <span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">//</span><span style="font-style: italic; color: rgb(0,128,0)" class="code-comment">It should be turn off the Light now</span></pre>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">So, you see, you can vary both the switches and the electrical equipments without any effect on the other, and connecting an abstraction of the electrical equipment with a switch (via encapsulation) is letting you do that. This design looks elegant and good. The Gang of Four has named this a pattern: The Bridge Pattern.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: Cool. I think I've understood the idea. Basically, two systems shouldn't be connected or dependent on another directly. Rather, they should be connected or dependent via abstraction (as the Dependency Inversion principle and the Open-Closed principle say) so that they are loosely coupled, and thus we are able to change our implementation when required without much effect on the other part of the system.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: You got it perfect darling. Let's see how the Bridge Pattern is defined:</p>
<h2 style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; color: rgb(255,153,0); font-size: 13pt; font-weight: bold">"Decouple an abstraction from its implementation so that the two can vary independently"</h2>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">You will see that our design perfectly matches the definition. If you have a class designer (in Visual Studio, you can do that, and other modern IDEs should also support this feature), you will see that you have a class diagram similar to the following:</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><img style="overflow-x: auto; overflow-y: auto" src="http://www.codeproject.com/KB/architecture/LearningDesignPatterns1/bridge.gif" width="448" height="293" complete="true"  alt="" /></p>
<div style="font-style: italic; font-size: 8pt; font-weight: bold" class="Caption">Class diagram of Bridge pattern.</div>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">Here,<span class="Apple-converted-space">&nbsp;</span><strong>Abstraction</strong><span class="Apple-converted-space">&nbsp;</span>is the base<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">Switch</code><span class="Apple-converted-space">&nbsp;</span>class.<span class="Apple-converted-space">&nbsp;</span><strong>RefinedAbstraction</strong><span class="Apple-converted-space">&nbsp;</span>is the specific switch classes (<code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">FancySwitch</code>,<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">NormalSwitch</code><span class="Apple-converted-space">&nbsp;</span>etc.).<span class="Apple-converted-space">&nbsp;</span><strong>Implementor</strong><span class="Apple-converted-space">&nbsp;</span>is the<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">IElectricalEquipment</code><span class="Apple-converted-space">&nbsp;</span>interface.<strong>ConcreteImplementorA</strong><span class="Apple-converted-space">&nbsp;</span>and<span class="Apple-converted-space">&nbsp;</span><strong>ConcreteImplementorB</strong><span class="Apple-converted-space">&nbsp;</span>are the<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">Fan</code><span class="Apple-converted-space">&nbsp;</span>and<span class="Apple-converted-space">&nbsp;</span><code style="font: 11pt 'Courier New', Courier, mono; color: rgb(153,0,0)">Light</code><span class="Apple-converted-space">&nbsp;</span>classes.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: Let me ask you a question, just curious. There are many other patterns as you said, why did you start with the Bridge pattern? Any important reason?</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: A very good question. Yes, I started with the Bridge pattern and not any other pattern (unlike many others) because of a reason. I believe the Bridge pattern is the base of all Object Oriented Design Patterns. You see:</p>
<ul><li style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">It teaches how to think abstract, which is the key concept of all Object Oriented Design Patterns.</li><li style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">It implements the basic OOD principles.</li><li style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">It is easy to understand.</li><li style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt">If this pattern is understood correctly, learning other Design Patterns becomes easy.</li></ul>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: Do you think I have understood it correctly?</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: I think you have understood it perfectly darling.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: So, what's next?</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Shubho</strong>: By understanding the Bridge pattern, we have just started to understand the concepts of Design Patterns. In our next conversation, we would learn other Design Patterns, and I hope you won't get bored learning them.</p>
<p style="line-height: 1.2em; font-family: Verdana, Arial, sans-serif; font-size: 10pt"><strong>Farhana</strong>: I won't. Believe me.<br /><br />from:<br /><a href="http://www.codeproject.com/KB/architecture/LearningDesignPatterns1.aspx">http://www.codeproject.com/KB/architecture/LearningDesignPatterns1.aspx</a></p></span></span><img src ="http://www.cppblog.com/beautykingdom/aggbug/148264.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2011-06-08 14:14 <a href="http://www.cppblog.com/beautykingdom/archive/2011/06/08/148264.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>How to explain OOD to my wife-code project《转载》</title><link>http://www.cppblog.com/beautykingdom/archive/2011/06/08/148263.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Wed, 08 Jun 2011 05:45:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2011/06/08/148263.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/148263.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2011/06/08/148263.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/148263.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/148263.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: IntroductionMy wife Farhana wants to resume her career as a software developer (she started her career as a software developer, but couldn't proceed much because of our first child's birth), and the...&nbsp;&nbsp;<a href='http://www.cppblog.com/beautykingdom/archive/2011/06/08/148263.html'>阅读全文</a><img src ="http://www.cppblog.com/beautykingdom/aggbug/148263.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2011-06-08 13:45 <a href="http://www.cppblog.com/beautykingdom/archive/2011/06/08/148263.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ifconf.c《转载》</title><link>http://www.cppblog.com/beautykingdom/archive/2011/05/20/146806.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Fri, 20 May 2011 04:30:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2011/05/20/146806.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/146806.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2011/05/20/146806.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/146806.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/146806.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: #include&nbsp;&lt;sys/types.h&gt;&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;sys/socket.h&gt;&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;sys/ioctl.h&gt;&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;netinet/in.h&gt;&nbsp;&nbsp;...&nbsp;&nbsp;<a href='http://www.cppblog.com/beautykingdom/archive/2011/05/20/146806.html'>阅读全文</a><img src ="http://www.cppblog.com/beautykingdom/aggbug/146806.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2011-05-20 12:30 <a href="http://www.cppblog.com/beautykingdom/archive/2011/05/20/146806.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vim configuration</title><link>http://www.cppblog.com/beautykingdom/archive/2011/05/01/145468.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Sun, 01 May 2011 10:31:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2011/05/01/145468.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/145468.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2011/05/01/145468.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/145468.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/145468.html</trackback:ping><description><![CDATA[set showcmd&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;" Show (partial) command in status line.<br />set showmatch&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;" Show matching brackets.<br />set ignorecase&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;" Do case insensitive matching<br />set smartcase&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;" Do smart case matching<br />set incsearch&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;" Incremental search<br />set autowrite&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;" Automatically save before commands like :next and :make<br />set hidden&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " Hide buffers when they are abandoned<br />set mouse=a&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;" Enable mouse usage (all modes)<br />set nu&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;" set line no on each line&nbsp;<span style="widows: 2; text-transform: none; background-color: rgb(245,247,248); text-indent: 0px; letter-spacing: normal; font: 12px/15px 宋体, Arial; white-space: normal; orphans: 2; color: rgb(0,0,0); word-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"> <br />
<p style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt"></span>&nbsp;</p>
<ul style="list-style: disc none outside; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; padding-top: 0px" type="disc"><li style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">使用<span style="line-height: 1.5">ctrl + r&nbsp;</span>可以搜索历史命令并执行</span></li><li style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">使用<span style="line-height: 1.5">history</span>显示历史，<span style="line-height: 1.5">!!</span>执行上一条命令，<span style="line-height: 1.5">!num</span>执行第<span style="line-height: 1.5">num</span>条命令</span></li><li style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">使用<span style="line-height: 1.5">vi</span>时，<span style="line-height: 1.5">q</span>！调出编辑历史</span></li><li style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">到行首<span style="line-height: 1.5">0</span>，行尾<span style="line-height: 1.5">$</span>，第一个非空格<span style="line-height: 1.5">^</span></span></li><li style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">不退出<span style="line-height: 1.5">vi</span>能直接执行命令，如<span style="line-height: 1.5">make</span></span></li><li style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">V</span><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">模式：正常（<span style="line-height: 1.5">v</span>），行模式<span style="line-height: 1.5">(</span>大写<span style="line-height: 1.5">V)</span>，<span style="line-height: 1.5">block</span>模式（<span style="line-height: 1.5">Ctrl + v</span>）</span></li><li style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">V</span><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">模式下，<span style="line-height: 1.5">&lt;&gt;</span>缩进所有</span></li><li style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">u</span><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">撤销，<span style="line-height: 1.5">ctrl+r</span>反撤销</span></li><li style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">ctrl+a</span><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">跳到命令行首，<span style="line-height: 1.5">ctrl+e</span>跳到命令行尾</span></li><li style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">:s/src/dest/(g)&nbsp;</span><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">替换当前行第一个或所有</span></li><li style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">:%s/src/dest/g&nbsp;&nbsp;</span><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">替换全局第一个或所有、</span></li><li style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">bn,bp,bf,bl</span><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">用于切换缓冲区，<span style="line-height: 1.5">bd</span>删除缓冲区</span></li><li style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">*</span><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">（<span style="line-height: 1.5">#</span>）用于查找光标位置处的缓冲区</span></li><li style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">ctrl+], ctrl+T</span><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">用于跳转定义与声明</span></li><li style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">ctrl+p</span><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">，<span style="line-height: 1.5">ctrl+n</span>用于单词补全</span></li><li style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">ctrl+o</span><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">，<span style="line-height: 1.5">ctrl+i</span>用于鼠标前后位置跳转</span></li><li style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">!command</span><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">在<span style="line-height: 1.5">vi</span>中执行外部命令</span></li><li style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">调整窗口，<span style="line-height: 1.5">ctrl+w |</span>宽度最大化，加减宽度<span style="line-height: 1.5">&lt;&gt;</span></span></li><li style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">调整宽口，<span style="line-height: 1.5">ctrl+w _</span>高度最大化，加减高度<span style="line-height: 1.5">+-</span></span></li><li style="list-style: disc none outside; text-align: left; padding-bottom: 0px; line-height: 24px; margin: 0px; padding-left: 2em; padding-right: 0px; color: black; padding-top: 0px"><span style="line-height: 1.5; font-family: 宋体; font-size: 12pt">调整窗开，<span style="line-height: 1.5">Ctrl+w =,</span>使窗口等宽</span></li></ul></span><br /><br /><img src ="http://www.cppblog.com/beautykingdom/aggbug/145468.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2011-05-01 18:31 <a href="http://www.cppblog.com/beautykingdom/archive/2011/05/01/145468.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>&lt;转&gt;how to start a kernel thread</title><link>http://www.cppblog.com/beautykingdom/archive/2011/03/22/142512.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Tue, 22 Mar 2011 13:08:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2011/03/22/142512.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/142512.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2011/03/22/142512.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/142512.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/142512.html</trackback:ping><description><![CDATA[<span style="WIDOWS: 2; TEXT-TRANSFORM: none; TEXT-INDENT: 0px; BORDER-COLLAPSE: separate; FONT: medium 'Times New Roman'; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: rgb(0,0,0); WORD-SPACING: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class=Apple-style-span><span style="FONT-FAMILY: verdana, arial, sans-serif; FONT-SIZE: 13px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px" class=Apple-style-span>Linux Kernel Threads in Device Drivers<span class=Apple-converted-space>&nbsp;</span><br>Purpose<span class=Apple-converted-space>&nbsp;</span><br>This examples shows how to create and stop a kernel thread.<span class=Apple-converted-space>&nbsp;</span><br>The driver is implemented as a loadable module. In the init_module() routine five kernel threads are created. This kernel threads sleep one second, wake up, print a message and fall asleep again. On unload of the module (cleanup_module), the kernel threads are killed.<span class=Apple-converted-space>&nbsp;</span><br>The example has been tested with Linux kernel 2.4.2 on Intel (uni processor only) and Alpha platform (COMPAQ Personal Workstation 500au (uni processor), DS20 and ES40 (SMP).<span class=Apple-converted-space>&nbsp;</span><br>A version for the 2.2 kernel can be found here. Note: depending on the context of the creator of the threads the new threads may inherit properties from the parent you do not want to have. The new version avoids this by having keventd create the threads. The 2.2. kernel do not have a keventd, so this approach is not implementable there.<span class=Apple-converted-space>&nbsp;</span><br><br>Functions in example<span class=Apple-converted-space>&nbsp;</span><br>start_kthread: creates a new kernel thread. Can be called from any process context but not from interrupt. The functions blocks until the thread started.<span class=Apple-converted-space>&nbsp;</span><br>stop_kthread: stop the thread. Can be called from any process context but the thread to be terminated. Cannot be called from interrupt context. The function blocks until the thread terminated.<span class=Apple-converted-space>&nbsp;</span><br>init_kthread: sets the environment of the new threads. Is to be called out of the created thread.<span class=Apple-converted-space>&nbsp;</span><br>exit_kthread: needs to be called by the thread to be terminated on exit<span class=Apple-converted-space>&nbsp;</span><br>Creation of new Thread<span class=Apple-converted-space>&nbsp;</span><br>A new thread is created with kernel_thread(). The thread inherits properties from its parents. To make sure that we do not get any weired properties, we let keventd create the new thread.<span class=Apple-converted-space>&nbsp;</span><br>The new thread is created with start_kthread(). It uses a semaphore to block until the new thread is running. A down() blocks the start_kthread() routine until the corresponding up() call in init_kthread() is executed.<span class=Apple-converted-space>&nbsp;</span><br>The new thread must call init_kthread() in order to let the creator continue.<span class=Apple-converted-space>&nbsp;</span><br>Stop of new Thread<span class=Apple-converted-space>&nbsp;</span><br>stop_kthread() sets a flag that the thread uses to determine whether do die or not and sends a SIGKILL to the thread. This signal causes the thread to be woken up. On wakeup it will check for the flag and then terminate itself by calling exit_kthread and returning from the thread function. With a semaphore the stop_kthread() function blocks until the thread terminated.<span class=Apple-converted-space>&nbsp;</span><br>Initialization of new Thread<span class=Apple-converted-space>&nbsp;</span><br>Within the new created thread, init_kthread() needs to be called. This function sets a signal mask, initialises a wait queue, the termination flag and sets a new name for the thread. With a up() call it notifies the creator that the setup is done.<span class=Apple-converted-space>&nbsp;</span><br>Exit of new Thread<span class=Apple-converted-space>&nbsp;</span><br>When the thread receives the notification to terminate itself, is calls the exit_kthread() function. It notifies the stop_kthread() function that it terminated with an up() call.<span class=Apple-converted-space>&nbsp;</span><br>The new Thread itself<span class=Apple-converted-space>&nbsp;</span><br>The new thread is implemented in the example_thread() function. It runs an endless loop (for(;;)). In the loop it falls asleep with the interruptible_sleep_on_timeout() function. It comes out of this function either when the timeout expires or when a signal got caught.<span class=Apple-converted-space>&nbsp;</span><br>The "work" in the thread is to print out a message with printk.<span class=Apple-converted-space>&nbsp;</span><br>Kernel Versions<span class=Apple-converted-space>&nbsp;</span><br>The example has been tested on 2.4.2.<span class=Apple-converted-space>&nbsp;</span><br>Example Device Driver Code<span class=Apple-converted-space>&nbsp;</span><br>The example consists of four files: kthread.h, kthread.c, thread_drv.c and a Makefile<span class=Apple-converted-space>&nbsp;</span><br>kthread.h<span class=Apple-converted-space>&nbsp;</span><br>#ifndef _KTHREAD_H<span class=Apple-converted-space>&nbsp;</span><br>#define _KTHREAD_H<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;linux/config.h&gt;<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;linux/version.h&gt;<span class=Apple-converted-space>&nbsp;</span><br><br>#include &lt;linux/kernel.h&gt;<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;linux/sched.h&gt;<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;linux/tqueue.h&gt;<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;linux/wait.h&gt;<span class=Apple-converted-space>&nbsp;</span><br><br>#include &lt;asm/unistd.h&gt;<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;asm/semaphore.h&gt;<span class=Apple-converted-space>&nbsp;</span><br><br>/* a structure to store all information we need<span class=Apple-converted-space>&nbsp;</span><br>for our thread */<span class=Apple-converted-space>&nbsp;</span><br>typedef struct kthread_struct<span class=Apple-converted-space>&nbsp;</span><br>{<span class=Apple-converted-space>&nbsp;</span><br>/* private data */<span class=Apple-converted-space>&nbsp;</span><br><br>/* Linux task structure of thread */<span class=Apple-converted-space>&nbsp;</span><br>struct task_struct *thread;<span class=Apple-converted-space>&nbsp;</span><br>/* Task queue need to launch thread */<span class=Apple-converted-space>&nbsp;</span><br>struct tq_struct tq;<span class=Apple-converted-space>&nbsp;</span><br>/* function to be started as thread */<span class=Apple-converted-space>&nbsp;</span><br>void (*function) (struct kthread_struct *kthread);<span class=Apple-converted-space>&nbsp;</span><br>/* semaphore needed on start and creation of thread. */<span class=Apple-converted-space>&nbsp;</span><br>struct semaphore startstop_sem;<span class=Apple-converted-space>&nbsp;</span><br><br>/* public data */<span class=Apple-converted-space>&nbsp;</span><br><br>/* queue thread is waiting on. Gets initialized by<span class=Apple-converted-space>&nbsp;</span><br>init_kthread, can be used by thread itself.<span class=Apple-converted-space>&nbsp;</span><br>*/<span class=Apple-converted-space>&nbsp;</span><br>wait_queue_head_t queue;<span class=Apple-converted-space>&nbsp;</span><br>/* flag to tell thread whether to die or not.<span class=Apple-converted-space>&nbsp;</span><br>When the thread receives a signal, it must check<span class=Apple-converted-space>&nbsp;</span><br>the value of terminate and call exit_kthread and terminate<span class=Apple-converted-space>&nbsp;</span><br>if set.<span class=Apple-converted-space>&nbsp;</span><br>*/<span class=Apple-converted-space>&nbsp;</span><br>int terminate;<span class=Apple-converted-space>&nbsp;</span><br>/* additional data to pass to kernel thread */<span class=Apple-converted-space>&nbsp;</span><br>void *arg;<span class=Apple-converted-space>&nbsp;</span><br>} kthread_t;<span class=Apple-converted-space>&nbsp;</span><br><br>/* prototypes */<span class=Apple-converted-space>&nbsp;</span><br><br>/* start new kthread (called by creator) */<span class=Apple-converted-space>&nbsp;</span><br>void start_kthread(void (*func)(kthread_t *), kthread_t *kthread);<span class=Apple-converted-space>&nbsp;</span><br><br>/* stop a running thread (called by "killer") */<span class=Apple-converted-space>&nbsp;</span><br>void stop_kthread(kthread_t *kthread);<span class=Apple-converted-space>&nbsp;</span><br><br>/* setup thread environment (called by new thread) */<span class=Apple-converted-space>&nbsp;</span><br>void init_kthread(kthread_t *kthread, char *name);<span class=Apple-converted-space>&nbsp;</span><br><br>/* cleanup thread environment (called by thread upon receiving termination signal) */<span class=Apple-converted-space>&nbsp;</span><br>void exit_kthread(kthread_t *kthread);<span class=Apple-converted-space>&nbsp;</span><br><br>#endif<span class=Apple-converted-space>&nbsp;</span><br><br>kthread.c<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;linux/config.h&gt;<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;linux/version.h&gt;<span class=Apple-converted-space>&nbsp;</span><br><br>#if defined(MODVERSIONS)<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;linux/modversions.h&gt;<span class=Apple-converted-space>&nbsp;</span><br>#endif<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;linux/kernel.h&gt;<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;linux/sched.h&gt;<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;linux/tqueue.h&gt;<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;linux/wait.h&gt;<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;linux/signal.h&gt;<span class=Apple-converted-space>&nbsp;</span><br><br>#include &lt;asm/semaphore.h&gt;<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;asm/smplock.h&gt;<span class=Apple-converted-space>&nbsp;</span><br><br>#include "kthread.h"<span class=Apple-converted-space>&nbsp;</span><br><br>/* private functions */<span class=Apple-converted-space>&nbsp;</span><br>static void kthread_launcher(void *data)<span class=Apple-converted-space>&nbsp;</span><br>{<span class=Apple-converted-space>&nbsp;</span><br>kthread_t *kthread = data;<span class=Apple-converted-space>&nbsp;</span><br>kernel_thread((int (*)(void *))kthread-&gt;function, (void *)kthread, 0);<span class=Apple-converted-space>&nbsp;</span><br><br>}<span class=Apple-converted-space>&nbsp;</span><br><br>/* public functions */<span class=Apple-converted-space>&nbsp;</span><br><br>/* create a new kernel thread. Called by the creator. */<span class=Apple-converted-space>&nbsp;</span><br>void start_kthread(void (*func)(kthread_t *), kthread_t *kthread)<span class=Apple-converted-space>&nbsp;</span><br>{<span class=Apple-converted-space>&nbsp;</span><br>/* initialize the semaphore:<span class=Apple-converted-space>&nbsp;</span><br>we start with the semaphore locked. The new kernel<span class=Apple-converted-space>&nbsp;</span><br>thread will setup its stuff and unlock it. This<span class=Apple-converted-space>&nbsp;</span><br>control flow (the one that creates the thread) blocks<span class=Apple-converted-space>&nbsp;</span><br>in the down operation below until the thread has reached<span class=Apple-converted-space>&nbsp;</span><br>the up() operation.<span class=Apple-converted-space>&nbsp;</span><br>*/<span class=Apple-converted-space>&nbsp;</span><br>init_MUTEX_LOCKED(&amp;kthread-&gt;startstop_sem);<span class=Apple-converted-space>&nbsp;</span><br><br>/* store the function to be executed in the data passed to<span class=Apple-converted-space>&nbsp;</span><br>the launcher */<span class=Apple-converted-space>&nbsp;</span><br>kthread-&gt;function=func;<span class=Apple-converted-space>&nbsp;</span><br><br>/* create the new thread my running a task through keventd */<span class=Apple-converted-space>&nbsp;</span><br><br>/* initialize the task queue structure */<span class=Apple-converted-space>&nbsp;</span><br>kthread-&gt;tq.sync = 0;<span class=Apple-converted-space>&nbsp;</span><br>INIT_LIST_HEAD(&amp;kthread-&gt;tq.list);<span class=Apple-converted-space>&nbsp;</span><br>kthread-&gt;tq.routine = kthread_launcher;<span class=Apple-converted-space>&nbsp;</span><br>kthread-&gt;tq.data = kthread;<span class=Apple-converted-space>&nbsp;</span><br><br>/* and schedule it for execution */<span class=Apple-converted-space>&nbsp;</span><br>schedule_task(&amp;kthread-&gt;tq);<span class=Apple-converted-space>&nbsp;</span><br><br>/* wait till it has reached the setup_thread routine */<span class=Apple-converted-space>&nbsp;</span><br>down(&amp;kthread-&gt;startstop_sem);<span class=Apple-converted-space>&nbsp;</span><br><br>}<span class=Apple-converted-space>&nbsp;</span><br><br>/* stop a kernel thread. Called by the removing instance */<span class=Apple-converted-space>&nbsp;</span><br>void stop_kthread(kthread_t *kthread)<span class=Apple-converted-space>&nbsp;</span><br>{<span class=Apple-converted-space>&nbsp;</span><br>if (kthread-&gt;thread == NULL)<span class=Apple-converted-space>&nbsp;</span><br>{<span class=Apple-converted-space>&nbsp;</span><br>printk("stop_kthread: killing non existing thread!\n");<span class=Apple-converted-space>&nbsp;</span><br>return;<span class=Apple-converted-space>&nbsp;</span><br>}<span class=Apple-converted-space>&nbsp;</span><br><br>/* this function needs to be protected with the big<span class=Apple-converted-space>&nbsp;</span><br>kernel lock (lock_kernel()). The lock must be<span class=Apple-converted-space>&nbsp;</span><br>grabbed before changing the terminate<span class=Apple-converted-space>&nbsp;</span><br>flag and released after the down() call. */<span class=Apple-converted-space>&nbsp;</span><br>lock_kernel();<span class=Apple-converted-space>&nbsp;</span><br><br>/* initialize the semaphore. We lock it here, the<span class=Apple-converted-space>&nbsp;</span><br>leave_thread call of the thread to be terminated<span class=Apple-converted-space>&nbsp;</span><br>will unlock it. As soon as we see the semaphore<span class=Apple-converted-space>&nbsp;</span><br>unlocked, we know that the thread has exited.<span class=Apple-converted-space>&nbsp;</span><br>*/<span class=Apple-converted-space>&nbsp;</span><br>init_MUTEX_LOCKED(&amp;kthread-&gt;startstop_sem);<span class=Apple-converted-space>&nbsp;</span><br><br>/* We need to do a memory barrier here to be sure that<span class=Apple-converted-space>&nbsp;</span><br>the flags are visible on all CPUs.<span class=Apple-converted-space>&nbsp;</span><br>*/<span class=Apple-converted-space>&nbsp;</span><br>mb();<span class=Apple-converted-space>&nbsp;</span><br><br>/* set flag to request thread termination */<span class=Apple-converted-space>&nbsp;</span><br>kthread-&gt;terminate = 1;<span class=Apple-converted-space>&nbsp;</span><br><br>/* We need to do a memory barrier here to be sure that<span class=Apple-converted-space>&nbsp;</span><br>the flags are visible on all CPUs.<span class=Apple-converted-space>&nbsp;</span><br>*/<span class=Apple-converted-space>&nbsp;</span><br>mb();<span class=Apple-converted-space>&nbsp;</span><br>kill_proc(kthread-&gt;thread-&gt;pid, SIGKILL, 1);<span class=Apple-converted-space>&nbsp;</span><br><br>/* block till thread terminated */<span class=Apple-converted-space>&nbsp;</span><br>down(&amp;kthread-&gt;startstop_sem);<span class=Apple-converted-space>&nbsp;</span><br><br>/* release the big kernel lock */<span class=Apple-converted-space>&nbsp;</span><br>unlock_kernel();<span class=Apple-converted-space>&nbsp;</span><br><br>/* now we are sure the thread is in zombie state. We<span class=Apple-converted-space>&nbsp;</span><br>notify keventd to clean the process up.<span class=Apple-converted-space>&nbsp;</span><br>*/<span class=Apple-converted-space>&nbsp;</span><br>kill_proc(2, SIGCHLD, 1);<span class=Apple-converted-space>&nbsp;</span><br><br>}<span class=Apple-converted-space>&nbsp;</span><br><br>/* initialize new created thread. Called by the new thread. */<span class=Apple-converted-space>&nbsp;</span><br>void init_kthread(kthread_t *kthread, char *name)<span class=Apple-converted-space>&nbsp;</span><br>{<span class=Apple-converted-space>&nbsp;</span><br>/* lock the kernel. A new kernel thread starts without<span class=Apple-converted-space>&nbsp;</span><br>the big kernel lock, regardless of the lock state<span class=Apple-converted-space>&nbsp;</span><br>of the creator (the lock level is *not* inheritated)<span class=Apple-converted-space>&nbsp;</span><br>*/<span class=Apple-converted-space>&nbsp;</span><br>lock_kernel();<span class=Apple-converted-space>&nbsp;</span><br><br>/* fill in thread structure */<span class=Apple-converted-space>&nbsp;</span><br>kthread-&gt;thread = current;<span class=Apple-converted-space>&nbsp;</span><br><br>/* set signal mask to what we want to respond */<span class=Apple-converted-space>&nbsp;</span><br>siginitsetinv(&amp;current-&gt;blocked, sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM));<span class=Apple-converted-space>&nbsp;</span><br><br>/* initialise wait queue */<span class=Apple-converted-space>&nbsp;</span><br>init_waitqueue_head(&amp;kthread-&gt;queue);<span class=Apple-converted-space>&nbsp;</span><br><br>/* initialise termination flag */<span class=Apple-converted-space>&nbsp;</span><br>kthread-&gt;terminate = 0;<span class=Apple-converted-space>&nbsp;</span><br><br>/* set name of this process (max 15 chars + 0 !) */<span class=Apple-converted-space>&nbsp;</span><br>sprintf(current-&gt;comm, name);<span class=Apple-converted-space>&nbsp;</span><br><br>/* let others run */<span class=Apple-converted-space>&nbsp;</span><br>unlock_kernel();<span class=Apple-converted-space>&nbsp;</span><br><br>/* tell the creator that we are ready and let him continue */<span class=Apple-converted-space>&nbsp;</span><br>up(&amp;kthread-&gt;startstop_sem);<span class=Apple-converted-space>&nbsp;</span><br><br>}<span class=Apple-converted-space>&nbsp;</span><br><br>/* cleanup of thread. Called by the exiting thread. */<span class=Apple-converted-space>&nbsp;</span><br>void exit_kthread(kthread_t *kthread)<span class=Apple-converted-space>&nbsp;</span><br>{<span class=Apple-converted-space>&nbsp;</span><br>/* we are terminating */<span class=Apple-converted-space>&nbsp;</span><br><br>/* lock the kernel, the exit will unlock it */<span class=Apple-converted-space>&nbsp;</span><br>lock_kernel();<span class=Apple-converted-space>&nbsp;</span><br>kthread-&gt;thread = NULL;<span class=Apple-converted-space>&nbsp;</span><br>mb();<span class=Apple-converted-space>&nbsp;</span><br><br>/* notify the stop_kthread() routine that we are terminating. */<span class=Apple-converted-space>&nbsp;</span><br>up(&amp;kthread-&gt;startstop_sem);<span class=Apple-converted-space>&nbsp;</span><br>/* the kernel_thread that called clone() does a do_exit here. */<span class=Apple-converted-space>&nbsp;</span><br><br>/* there is no race here between execution of the "killer" and real termination<span class=Apple-converted-space>&nbsp;</span><br>of the thread (race window between up and do_exit), since both the<span class=Apple-converted-space>&nbsp;</span><br>thread and the "killer" function are running with the kernel lock held.<span class=Apple-converted-space>&nbsp;</span><br>The kernel lock will be freed after the thread exited, so the code<span class=Apple-converted-space>&nbsp;</span><br>is really not executed anymore as soon as the unload functions gets<span class=Apple-converted-space>&nbsp;</span><br>the kernel lock back.<span class=Apple-converted-space>&nbsp;</span><br>The init process may not have made the cleanup of the process here,<span class=Apple-converted-space>&nbsp;</span><br>but the cleanup can be done safely with the module unloaded.<span class=Apple-converted-space>&nbsp;</span><br>*/<span class=Apple-converted-space>&nbsp;</span><br><br>}<span class=Apple-converted-space>&nbsp;</span><br><br>thread_drv.c<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;linux/config.h&gt;<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;linux/version.h&gt;<span class=Apple-converted-space>&nbsp;</span><br><br>#include &lt;linux/module.h&gt;<span class=Apple-converted-space>&nbsp;</span><br>#if defined(MODVERSIONS)<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;linux/modversions.h&gt;<span class=Apple-converted-space>&nbsp;</span><br>#endif<span class=Apple-converted-space>&nbsp;</span><br><br>#include &lt;linux/kernel.h&gt;<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;linux/string.h&gt;<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;linux/errno.h&gt;<span class=Apple-converted-space>&nbsp;</span><br>#include &lt;linux/sched.h&gt;<span class=Apple-converted-space>&nbsp;</span><br><br>#include "kthread.h"<span class=Apple-converted-space>&nbsp;</span><br><br>#define NTHREADS 5<span class=Apple-converted-space>&nbsp;</span><br><br>/* the variable that contains the thread data */<span class=Apple-converted-space>&nbsp;</span><br>kthread_t example[NTHREADS];<span class=Apple-converted-space>&nbsp;</span><br><br>/* prototype for the example thread */<span class=Apple-converted-space>&nbsp;</span><br>static void example_thread(kthread_t *kthread);<span class=Apple-converted-space>&nbsp;</span><br><br>/* load the module */<span class=Apple-converted-space>&nbsp;</span><br>int init_module(void)<span class=Apple-converted-space>&nbsp;</span><br>{<span class=Apple-converted-space>&nbsp;</span><br>int i;<span class=Apple-converted-space>&nbsp;</span><br><br>/* create new kernel threads */<span class=Apple-converted-space>&nbsp;</span><br>for (i=0; i &lt;NTHREADS; i++)<span class=Apple-converted-space>&nbsp;</span><br>start_kthread(example_thread, &amp;example<em>);<span class=Apple-converted-space>&nbsp;</span><br><br>return(0);<span class=Apple-converted-space>&nbsp;</span><br>}<span class=Apple-converted-space>&nbsp;</span><br><br>/* remove the module */<span class=Apple-converted-space>&nbsp;</span><br>void cleanup_module(void)<span class=Apple-converted-space>&nbsp;</span><br>{<span class=Apple-converted-space>&nbsp;</span><br>int i;<span class=Apple-converted-space>&nbsp;</span><br><br>/* terminate the kernel threads */<span class=Apple-converted-space>&nbsp;</span><br>for (i=0; i&lt;NTHREADS; i++)<span class=Apple-converted-space>&nbsp;</span><br>stop_kthread(&amp;example);<span class=Apple-converted-space>&nbsp;</span><br><br>return;<span class=Apple-converted-space>&nbsp;</span><br>}<span class=Apple-converted-space>&nbsp;</span><br><br>/* this is the thread function that we are executing */<span class=Apple-converted-space>&nbsp;</span><br>static void example_thread(kthread_t *kthread)<span class=Apple-converted-space>&nbsp;</span><br>{<span class=Apple-converted-space>&nbsp;</span><br>/* setup the thread environment */<span class=Apple-converted-space>&nbsp;</span><br>init_kthread(kthread, "example thread");<span class=Apple-converted-space>&nbsp;</span><br><br>printk("hi, here is the kernel thread\n");<span class=Apple-converted-space>&nbsp;</span><br><br>/* an endless loop in which we are doing our work */<span class=Apple-converted-space>&nbsp;</span><br>for(;;)<span class=Apple-converted-space>&nbsp;</span><br>{<span class=Apple-converted-space>&nbsp;</span><br>/* fall asleep for one second */<span class=Apple-converted-space>&nbsp;</span><br>interruptible_sleep_on_timeout(&amp;kthread-&gt;queue, HZ);<span class=Apple-converted-space>&nbsp;</span><br><br>/* We need to do a memory barrier here to be sure that<span class=Apple-converted-space>&nbsp;</span><br>the flags are visible on all CPUs.<span class=Apple-converted-space>&nbsp;</span><br>*/<span class=Apple-converted-space>&nbsp;</span><br>mb();<span class=Apple-converted-space>&nbsp;</span><br><br>/* here we are back from sleep, either due to the timeout<span class=Apple-converted-space>&nbsp;</span><br>(one second), or because we caught a signal.<span class=Apple-converted-space>&nbsp;</span><br>*/<span class=Apple-converted-space>&nbsp;</span><br>if (kthread-&gt;terminate)<span class=Apple-converted-space>&nbsp;</span><br>{<span class=Apple-converted-space>&nbsp;</span><br>/* we received a request to terminate ourself */<span class=Apple-converted-space>&nbsp;</span><br>break;<span class=Apple-converted-space>&nbsp;</span><br>}<span class=Apple-converted-space>&nbsp;</span><br><br>/* this is normal work to do */<span class=Apple-converted-space>&nbsp;</span><br>printk("example thread: thread woke up\n");<span class=Apple-converted-space>&nbsp;</span><br>}<span class=Apple-converted-space>&nbsp;</span><br>/* here we go only in case of termination of the thread */<span class=Apple-converted-space>&nbsp;</span><br><br>/* cleanup the thread, leave */<span class=Apple-converted-space>&nbsp;</span><br>exit_kthread(kthread);<span class=Apple-converted-space>&nbsp;</span><br><br>/* returning from the thread here calls the exit functions */<span class=Apple-converted-space>&nbsp;</span><br>}<span class=Apple-converted-space>&nbsp;</span><br><br>Makefile<span class=Apple-converted-space>&nbsp;</span><br># set to your kernel tree<span class=Apple-converted-space>&nbsp;</span><br>KERNEL = /usr/src/linux<span class=Apple-converted-space>&nbsp;</span><br><br># get the Linux architecture. Needed to find proper include file for CFLAGS<span class=Apple-converted-space>&nbsp;</span><br>ARCH=$(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)<br># set default flags to compile module<span class=Apple-converted-space>&nbsp;</span><br>CFLAGS = -D__KERNEL__ -DMODULE -I$(KERNEL)/include<span class=Apple-converted-space>&nbsp;</span><br>CFLAGS+= -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing<span class=Apple-converted-space>&nbsp;</span><br><br>all: thread_mod.o<span class=Apple-converted-space>&nbsp;</span><br><br># get configuration of kernel<span class=Apple-converted-space>&nbsp;</span><br>include $(KERNEL)/.config<span class=Apple-converted-space>&nbsp;</span><br># modify CFLAGS with architecture specific flags<span class=Apple-converted-space>&nbsp;</span><br>include $(KERNEL)/arch/${ARCH}/Makefile<span class=Apple-converted-space>&nbsp;</span><br><br># enable the module versions, if configured in kernel source tree<span class=Apple-converted-space>&nbsp;</span><br>ifdef CONFIG_MODVERSIONS<span class=Apple-converted-space>&nbsp;</span><br>CFLAGS+= -DMODVERSIONS -include $(KERNEL)/include/linux/modversions.h<span class=Apple-converted-space>&nbsp;</span><br>endif<span class=Apple-converted-space>&nbsp;</span><br># enable SMP, if configured in kernel source tree<span class=Apple-converted-space>&nbsp;</span><br>ifdef CONFIG_SMP<span class=Apple-converted-space>&nbsp;</span><br>CFLAGS+= -D__SMP__<span class=Apple-converted-space>&nbsp;</span><br>endif<span class=Apple-converted-space>&nbsp;</span><br><br># note: we are compiling the driver object file and then linking<span class=Apple-converted-space>&nbsp;</span><br># we link it into the module. With just one object file as in<span class=Apple-converted-space>&nbsp;</span><br># this example this is not needed. We can just load the object<span class=Apple-converted-space>&nbsp;</span><br># file produced by gcc<span class=Apple-converted-space>&nbsp;</span><br># link the thread driver module<span class=Apple-converted-space>&nbsp;</span><br>thread_mod.o: thread_drv.o kthread.o<span class=Apple-converted-space>&nbsp;</span><br>ld -r -o thread_mod.o thread_drv.o kthread.o<span class=Apple-converted-space>&nbsp;</span><br># compile the kthread object file<span class=Apple-converted-space>&nbsp;</span><br>kthread.o: kthread.c kthread.h<span class=Apple-converted-space>&nbsp;</span><br>gcc $(CFLAGS) -c kthread.c<span class=Apple-converted-space>&nbsp;</span><br># compile the thread driver<span class=Apple-converted-space>&nbsp;</span><br>thread_drv.o: thread_drv.c kthread.h<span class=Apple-converted-space>&nbsp;</span><br>gcc $(CFLAGS) -c thread_drv.c<span class=Apple-converted-space>&nbsp;</span><br><br>clean:<span class=Apple-converted-space>&nbsp;</span><br>rm -f *.o<span class=Apple-converted-space>&nbsp;</span><br><br>Bugs<span class=Apple-converted-space>&nbsp;</span><br>The code assumes that keventd is running with PID 2.<span class=Apple-converted-space>&nbsp;</span><br>Comments, Corrections<span class=Apple-converted-space>&nbsp;</span><br>Please send comments, corrections etc. to the address below.<br><br>from:<br></em><a href="http://www.linuxforum.net/forum/showflat.php?Cat=&amp;Board=linuxK&amp;Number=282973&amp;page=15&amp;view=collapsed&amp;sb=5&amp;o=all"><u><font color=#0000ff size=3 face="Times New Roman">http://www.linuxforum.net/forum/showflat.php?Cat=&amp;Board=linuxK&amp;Number=282973&amp;page=15&amp;view=collapsed&amp;sb=5&amp;o=all</font></u></a><br><br><br></span></span>
<img src ="http://www.cppblog.com/beautykingdom/aggbug/142512.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2011-03-22 21:08 <a href="http://www.cppblog.com/beautykingdom/archive/2011/03/22/142512.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>什么是段错误</title><link>http://www.cppblog.com/beautykingdom/archive/2011/03/20/142281.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Sun, 20 Mar 2011 08:32:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2011/03/20/142281.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/142281.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2011/03/20/142281.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/142281.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/142281.html</trackback:ping><description><![CDATA[<br>所谓的段错误就是指访问的内存超出了系统所给这个程序的内存空间，通常这个值是由gdtr来保存的，<br>他是一个48位的寄存器，其中的32位是保存由它指向的gdt表，后13位保存相应于gdt的下标，最后3位<br>包括了程序是否在内存中以及程序的在cpu中的运行级别,指向的gdt是由以64位为一个单位的表，在这<br>张表中就保存着程序运行的代码段以及数据段的起始地址以及与此相应的段限和页面交换还有程序运<br>行级别还有内存粒度等等的信息。一旦一个程序发生了越界访问，cpu就会产生相应的异常保护，于<br>是segmentation fault就出现了。
<img src ="http://www.cppblog.com/beautykingdom/aggbug/142281.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2011-03-20 16:32 <a href="http://www.cppblog.com/beautykingdom/archive/2011/03/20/142281.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Doubly-linked list</title><link>http://www.cppblog.com/beautykingdom/archive/2011/01/02/137879.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Sun, 02 Jan 2011 04:04:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2011/01/02/137879.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/137879.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2011/01/02/137879.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/137879.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/137879.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: basic doubly linked list algorithm&nbsp;&nbsp;<a href='http://www.cppblog.com/beautykingdom/archive/2011/01/02/137879.html'>阅读全文</a><img src ="http://www.cppblog.com/beautykingdom/aggbug/137879.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2011-01-02 12:04 <a href="http://www.cppblog.com/beautykingdom/archive/2011/01/02/137879.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux c 大文件使用</title><link>http://www.cppblog.com/beautykingdom/archive/2010/12/10/136040.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Fri, 10 Dec 2010 03:36:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/12/10/136040.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/136040.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/12/10/136040.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/136040.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/136040.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="border-collapse: separate; color: #000000; font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"><span class="Apple-style-span" style="color: #6a7376; font-family: Tahoma; font-size: 12px; line-height: 24px;">
<p style="line-height: normal;">支持大文件的两种方式：</p>
<p style="line-height: normal;">1、gcc 加 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE</p>
<p style="line-height: normal;"><strong style="line-height: normal;"><font style="line-height: normal;" color="#ff0000">2、注意一定要定义在include之前</font></strong></p>
<p style="line-height: normal;">#define _LARGEFILE_SOURCE<br style="line-height: normal;">#define _LARGEFILE64_SOURCE<br style="line-height: normal;">#define _FILE_OFFSET_BITS 64</p>
<p style="line-height: normal;">建议两种方式都加上。</p>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><strong style="line-height: normal;">如何create大文件</strong></div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">要大就非常大，1T吧。</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">有两种方法：</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><wbr style="line-height: normal;"></div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><strong style="line-height: normal;">一.dd</strong><br style="line-height: normal;"><font style="line-height: normal;" color="#ff0000">dd if=/dev/zero of=1T.img bs=1G seek=1024 count=0</font><br style="line-height: normal;">bs=1G表示每一次读写1G数据，count=0表示读写0次，seek=1024表示略过1024个Block不写，前面block size是1G，所以共略过1T！<br style="line-height: normal;">这是创建大型sparse文件最简单的方法。</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><wbr style="line-height: normal;"></div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><strong style="line-height: normal;">二.ftruncate64/ftruncate</strong><br style="line-height: normal;">如果用系统函数就稍微有些麻烦，因为涉及到宏的问题。我会结合一个实际例子详细说明，其中OPTION标志的就是测试项。<br style="line-height: normal;"><em style="line-height: normal;">文件sparse.c:</em></div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><wbr style="line-height: normal;"></div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><font style="line-height: normal;" color="#ff0000">//OPTION 1:是否定义与大文件相关的宏</font><br style="line-height: normal;">#define _LARGEFILE_SOURCE<br style="line-height: normal;">#define _LARGEFILE64_SOURCE<br style="line-height: normal;">#define _FILE_OFFSET_BITS 64</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><wbr style="line-height: normal;"></div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">#include &lt;stdio.h&gt;<br style="line-height: normal;">#include &lt;sys/types.h&gt;<br style="line-height: normal;">#include &lt;sys/stat.h&gt;<br style="line-height: normal;">#include &lt;fcntl.h&gt;<br style="line-height: normal;">#include &lt;errno.h&gt;<br style="line-height: normal;">#include &lt;string.h&gt;</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">#define FILENAME "bigfile"<br style="line-height: normal;">#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)<br style="line-height: normal;">int main(int argc, char **argv)<br style="line-height: normal;">{<br style="line-height: normal;"><wbr style="line-height: normal;">int fd, ret;<br style="line-height: normal;"><wbr style="line-height: normal;">off_t offset;</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><wbr style="line-height: normal;">int total = 0;<br style="line-height: normal;"><wbr style="line-height: normal;">if ( argc &gt;= 2 )<br style="line-height: normal;"><wbr style="line-height: normal;">{<br style="line-height: normal;"><wbr style="line-height: normal;"><wbr style="line-height: normal;"><wbr style="line-height: normal;">total = atol(argv[1]);<br style="line-height: normal;"><wbr style="line-height: normal;"><wbr style="line-height: normal;"><wbr style="line-height: normal;">printf("total=%d\n", total);<br style="line-height: normal;"><wbr style="line-height: normal;">}</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><wbr style="line-height: normal;"><br style="line-height: normal;"><wbr style="line-height: normal;"><font style="line-height: normal;" color="#ff0000">//OPTION 2:是否有O_LARGEFILE选项</font><br style="line-height: normal;"><wbr style="line-height: normal;">//fd = open(FILENAME, O_RDWR|O_CREAT|O_LARGEFILE, 0644);<br style="line-height: normal;"><wbr style="line-height: normal;">fd = open(FILENAME, O_RDWR|O_CREAT, 0644);<br style="line-height: normal;"><wbr style="line-height: normal;">if (fd &lt; 0) {<br style="line-height: normal;"><wbr style="line-height: normal;"><wbr style="line-height: normal;"><wbr style="line-height: normal;">perror(FILENAME);<br style="line-height: normal;"><wbr style="line-height: normal;"><wbr style="line-height: normal;"><wbr style="line-height: normal;">return -1;<br style="line-height: normal;"><wbr style="line-height: normal;">}<br style="line-height: normal;"><wbr style="line-height: normal;">offset = (off_t)total *1024ll*1024ll*1024ll;<br style="line-height: normal;"><wbr style="line-height: normal;">printf("offset=%ld\n", offset);</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><wbr style="line-height: normal;"></div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><wbr style="line-height: normal;"><font style="line-height: normal;" color="#ff0000">//OPTION 3：是否调用64位系统函数</font><br style="line-height: normal;"><wbr style="line-height: normal;">//if (ftruncate64(fd, offset) &lt; 0)<br style="line-height: normal;"><wbr style="line-height: normal;">if (ftruncate(fd, offset) &lt; 0)<br style="line-height: normal;"><wbr style="line-height: normal;">{<br style="line-height: normal;"><wbr style="line-height: normal;"><wbr style="line-height: normal;"><wbr style="line-height: normal;">printf("[%d]-ftruncate64 error: %s\n",<span class="Apple-converted-space">&nbsp;</span><wbr style="line-height: normal;">errno, strerror(errno));<br style="line-height: normal;"><wbr style="line-height: normal;"><wbr style="line-height: normal;"><wbr style="line-height: normal;">close(fd);<br style="line-height: normal;"><wbr style="line-height: normal;"><wbr style="line-height: normal;"><wbr style="line-height: normal;">return 0;<br style="line-height: normal;"><wbr style="line-height: normal;">}</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><wbr style="line-height: normal;">close(fd);<br style="line-height: normal;"><wbr style="line-height: normal;">printf("OK\n");</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><wbr style="line-height: normal;">return 0;<br style="line-height: normal;">}</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><wbr style="line-height: normal;"></div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><strong style="line-height: normal;">测试环境：</strong><br style="line-height: normal;">linux:/disk/test/big # gcc --version<br style="line-height: normal;">gcc (GCC) 3.3.5 20050117 (prerelease) (SUSE Linux)<br style="line-height: normal;">linux:/disk/test/big # uname -a<br style="line-height: normal;">Linux linux 2.6.11.4-20a-default #1 Wed Mar 23 21:52:37 UTC 2005 i686 i686 i386 GNU/Linux</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><wbr style="line-height: normal;"></div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><strong style="line-height: normal;">测试结果（伪码表示）：</strong><br style="line-height: normal;"><strong style="line-height: normal;">1.宏定义完全的情况下：</strong><br style="line-height: normal;">IF {O_LARGEFILE=TRUE &amp;&amp; ftruncate64=TRUE}<br style="line-height: normal;"><wbr style="line-height: normal;">OK；<br style="line-height: normal;">ELSEIF {O_LARGEFILE=FALSE &amp;&amp; ftruncate64=TRUE}<br style="line-height: normal;"><wbr style="line-height: normal;">OK；<br style="line-height: normal;">ELSEIF {O_LARGEFILE=FALSE &amp;&amp; ftruncate64=FALSE}<br style="line-height: normal;"><wbr style="line-height: normal;">运行不报错，但是不支持&gt;4G；<br style="line-height: normal;">ELSEIF {O_LARGEFILE=TRUE &amp;&amp; ftruncate64=FALSE}<br style="line-height: normal;"><wbr style="line-height: normal;">运行不报错，但是不支持&gt;4G；<br style="line-height: normal;">【<strong style="line-height: normal;">结论</strong>】：<font style="line-height: normal;" color="#ff0000">在宏定义完全的情况下，是否调用ftruncate64，是决定支持4G以上文件的关键，O_LARGEFILE无作用</font>。</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><wbr style="line-height: normal;"></div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><strong style="line-height: normal;">2.宏定义不完全：缺少_FILE_OFFSET_BITS</strong><br style="line-height: normal;">首先声明一点，<font style="line-height: normal;" color="#ff0000">O_LARGEFILE需要定义_LARGEFILE64_SOURCE</font>。<br style="line-height: normal;">IF {O_LARGEFILE=TRUE &amp;&amp; ftruncate64=TRUE}<br style="line-height: normal;"><wbr style="line-height: normal;">产生不正常超大文件；<br style="line-height: normal;">ELSEIF {O_LARGEFILE=FALSE &amp;&amp; ftruncate64=TRUE}<br style="line-height: normal;"><wbr style="line-height: normal;">产生不正常超大文件；<br style="line-height: normal;">ELSEIF {O_LARGEFILE=FALSE &amp;&amp; ftruncate64=FALSE}<br style="line-height: normal;"><wbr style="line-height: normal;">运行不报错，但是不支持&gt;2G；<br style="line-height: normal;">ELSEIF {O_LARGEFILE=TRUE &amp;&amp; ftruncate64=FALSE}<br style="line-height: normal;"><wbr style="line-height: normal;">运行不报错，但是不支持&gt;4G；<br style="line-height: normal;">【<strong style="line-height: normal;">结论</strong>】：<font style="line-height: normal;" color="#ff0000">未定义_FILE_OFFSET_BITS的情况下，ftruncate64调用是非法的，会产生无法预料的后果，这里的测试就是产生一个超大文件(&gt;1T)，我也无法解释其原因；O_LARGEFILE的作用就是在32位系统中支持大文件系统,允许打开那些用31位（2G）都不能表示其长度的大文件；此外，off_t为unsigned int类型，也就是说最多只能达到4G，所以ftruncate最大支持4G文件。</font></div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><wbr style="line-height: normal;"></div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><strong style="line-height: normal;">总结一下</strong>：<font style="line-height: normal;" color="#ff0000">如果要支持超过2G的文件，至少需要定义_LARGEFILE64_SOURCE宏，并且设置O_LARGEFILE选项；如果要支持超过4G，需要定义所有上述的宏，并且调用ftruncate64；其余的搭配都是错误的！</font></div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;"><wbr style="line-height: normal;"></div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">【<strong style="line-height: normal;">附</strong>】：<br style="line-height: normal;">dd 的主要选项：<br style="line-height: normal;">指定数字的地方若以下列字符结尾乘以相应的数字:<br style="line-height: normal;">b=512, c=1, k=1024, w=2, m=1024k, g=1024m<br style="line-height: normal;">大小写不限。</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">if=file<br style="line-height: normal;">输入文件名，缺省为标准输入。</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">of=file<br style="line-height: normal;">输出文件名，缺省为标准输出。</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">ibs=bytes<br style="line-height: normal;">一次读入 bytes 个字节(即一个块大小为 bytes 个字节)。</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">obs=bytes<br style="line-height: normal;">一次写 bytes 个字节(即一个块大小为 bytes 个字节)。</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">bs=bytes<br style="line-height: normal;">同时设置读写块的大小为 bytes ，可代替 ibs 和 obs 。</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">cbs=bytes<br style="line-height: normal;">一次转换 bytes 个字节，即转换缓冲区大小。</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">skip=blocks<br style="line-height: normal;">从输入文件开头跳过 blocks 个块后再开始复制。</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">seek=blocks<br style="line-height: normal;">从输出文件开头跳过 blocks 个块后再开始复制。(通常只有当输出文件是磁盘或磁带时才有效)</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">count=blocks<br style="line-height: normal;">仅拷贝 blocks 个块，块大小等于 ibs 指定的字节数。</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">conv=conversion[,conversion...]<br style="line-height: normal;">用指定的参数转换文件。</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">转换参数:</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">ascii 转换 EBCDIC 为 ASCII。</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">ebcdic 转换 ASCII 为 EBCDIC。</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">ibm 转换 ASCII 为 alternate EBCDIC.</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">block 把每一行转换为长度为 cbs 的记录，不足部分用空格填充。</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">unblock<br style="line-height: normal;">使每一行的长度都为 cbs ，不足部分用空格填充。</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">lcase 把大写字符转换为小写字符。</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">ucase 把小写字符转换为大写字符。</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">noerror<br style="line-height: normal;">不显示错误</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">notrunc<br style="line-height: normal;">不截短输出文件。</div>
<div style="font-family: Arial; word-wrap: break-word; visibility: visible ! important; filter: none; font-size: 12px; line-height: normal;">sync 把每个输入块填充到ibs个字节，不足部分用空(NUL)字符补齐。<br><br><br><br>from:<br><a  href="http://hi.baidu.com/roxws/blog/item/785c4bcb61662ff853664f2d.html/cmtid/f990c324dee21627d50742e9">http://hi.baidu.com/roxws/blog/item/785c4bcb61662ff853664f2d.html/cmtid/f990c324dee21627d50742e9</a><br><br></div>
</span></span><img src ="http://www.cppblog.com/beautykingdom/aggbug/136040.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-12-10 11:36 <a href="http://www.cppblog.com/beautykingdom/archive/2010/12/10/136040.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Aix下查看占用端口的进程</title><link>http://www.cppblog.com/beautykingdom/archive/2010/12/06/135571.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Mon, 06 Dec 2010 04:08:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/12/06/135571.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/135571.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/12/06/135571.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/135571.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/135571.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="border-collapse: separate; color: #000000; font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"><span class="Apple-style-span" style="border-collapse: collapse; font-family: song,Verdana; font-size: 14px; line-height: 22px; text-align: left;">Issue the command:<span class="Apple-converted-space">&nbsp;</span><br style="word-wrap: break-word; line-height: normal;">rmsock `netstat -Aan | grep port | awk '{print $1}'` tcpcp<br><br>be sure to utilize the root previledge<span class="Apple-converted-space"> </span><br style="word-wrap: break-word; line-height: normal;"></span></span><br> <img src ="http://www.cppblog.com/beautykingdom/aggbug/135571.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-12-06 12:08 <a href="http://www.cppblog.com/beautykingdom/archive/2010/12/06/135571.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>The Linux Kernel Module Programming Guide</title><link>http://www.cppblog.com/beautykingdom/archive/2010/11/29/134974.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Mon, 29 Nov 2010 04:03:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/11/29/134974.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/134974.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/11/29/134974.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/134974.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/134974.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: The Linux Kernel Module Programming GuidePeter Jay SalzmanMichael BurianOri PomerantzCopyright &#169; 2001 Peter Jay Salzman2007-05-18 ver 2.6.4The Linux Kernel Module Programming Guide is a...&nbsp;&nbsp;<a href='http://www.cppblog.com/beautykingdom/archive/2010/11/29/134974.html'>阅读全文</a><img src ="http://www.cppblog.com/beautykingdom/aggbug/134974.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-11-29 12:03 <a href="http://www.cppblog.com/beautykingdom/archive/2010/11/29/134974.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>How does the DMA work</title><link>http://www.cppblog.com/beautykingdom/archive/2010/11/14/133602.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Sun, 14 Nov 2010 11:23:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/11/14/133602.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/133602.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/11/14/133602.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/133602.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/133602.html</trackback:ping><description><![CDATA[

<div><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">The DMA is another two chips on your motherboard (usually is an Intel 8237A-5 chips) that allow you (the programmer) to offload data transfers between I/O boards. DMA actually stands for 'Direct Memory Access'.</p><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">DMA can work: memory-&gt;I/O, I/O-&gt;memory. The memory-&gt;memory transfer doesn't work. It doesn't matter because ISA DMA is slow as hell and thus is unusable. Futhermore, using DMA for zeroing out memory would massacre the contents of memory caches.</p><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">What about caches and DMA? L1 and L2 caches work absolutely transparently. When DMA writes to memory, caches autmatically load or least invalidate the data that go into the memory. When DMA reads memory, caches supply the unwritten bytes so not old but new values are tranferred to the peripheral.</p><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">There are signals DACK<number>, DRQ<number>, and TC. When a peripheral wants to move a byte or 2 bytes into memory (is dependent on whether 8 bit or 16 bit DMA channel is in use -- 0,1,2,3 are 8-bit, 5,6,7 are 16-bit), it issues DRQ. DMA controller chats with CPU and after some time DMA controller issues DACK. Seeing DACK, the peripheral puts it's byte on data bus, DMA controller takes it and puts it in memory. If it was the last byte/word to move, DMA controller sets up also TC during the DACK. When peripheral sees TC, it is possible it will not want any more movements,</number></number></p><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">In the other direction, everything is the same, but first the byte/word is fetched from the memory and then DACK is generated and the peripheral takes the data.</p><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">DMA controller has only 8-bit address counter inside. There is external ALS573 counter for each chip so it makes programmer see it as DMA controller had 16 bits of address counter per channel inside. There are more 8 bits of address per channel of so called page register in LS612 that unfortunately do not increment as those in ALS573. All these 24 bits can address 16777216 of distict addresses.</p><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">Recapitulation: for each channel, independently, you see 16 bits of auto-incrementing counter, and 8 bits of page register which doesn't increment.</p><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">The difference between 16-bit DMA channels and 8-bit DMA channels is that the address bits for 16-bit channels are wired one bit left to the address bus so every address is 2 times bigger. The lowest bit is 0. The highest bit of page register would fit into bit 24 which is not on ISA so that it is left unconnected. The bus control logic is wired for 16-bit channels in a manner every single DMA transfer, a 16-bit cycle is generated, so ISA device puts 16 bits onto the bus at the time. I don't know what happens if you use 16-bit DMA channel with XT peripheral. I guess it could work but only be slower.</p><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">8-bit DMA: increments by 1, cycles inside 65536 bytes, addresses 16MB, moves 8 bits a time.</p><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">16-bit DMA: increments by 2, goes only over even addresses, cycles inside 131072 bytes, addresses 16MB, moves 16 bits a time. Uses 16-bit ISA I/O cycle so it takes less ticks to make one move that the 8-bit DMA.</p><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">An example of DMA usage would be the Sound Blaster's ability to play samples in the background. The CPU sets up the sound card and the DMA. When the DMA is told to 'go', it simply shovels the data from RAM to the card. Since this is done off-CPU, the CPU can do other things while the data is being transferred.</p><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">Enough basics. Here's how you program the DMA chip.</p><hr style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; "><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">When you want to start a DMA transfer, you need to know several things:</p><ul style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; list-style-type: none; list-style-position: initial; list-style-image: initial; font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; "><li style="list-style-type: none; list-style-position: initial; list-style-image: initial; margin-top: 0px; margin-right: 0px; margin-bottom: 20px; margin-left: 0px; ">Number of DMA channel you want to use</li><li style="list-style-type: none; list-style-position: initial; list-style-image: initial; margin-top: 0px; margin-right: 0px; margin-bottom: 20px; margin-left: 0px; ">What page to use</li><li style="list-style-type: none; list-style-position: initial; list-style-image: initial; margin-top: 0px; margin-right: 0px; margin-bottom: 20px; margin-left: 0px; ">The offset in the page</li><li style="list-style-type: none; list-style-position: initial; list-style-image: initial; margin-top: 0px; margin-right: 0px; margin-bottom: 20px; margin-left: 0px; ">The length</li><li style="list-style-type: none; list-style-position: initial; list-style-image: initial; margin-top: 0px; margin-right: 0px; margin-bottom: 20px; margin-left: 0px; ">How to tell you peripheral to ask for DMA</li></ul><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; "></p><ul style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; list-style-type: none; list-style-position: initial; list-style-image: initial; font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; "><li style="list-style-type: none; list-style-position: initial; list-style-image: initial; margin-top: 0px; margin-right: 0px; margin-bottom: 20px; margin-left: 0px; ">You cannot transfer more than 64K or 128K of data in one shot, and</li><li style="list-style-type: none; list-style-position: initial; list-style-image: initial; margin-top: 0px; margin-right: 0px; margin-bottom: 20px; margin-left: 0px; ">You cannot cross a page boundary. If you cross it, the lower 16 or 17 bits of address will simply wrap and you only suddenly jump 65536 or 131072 bytes lower that where you expected. It will be absolutely OK and no screw up will be performed. If you will take it in account in your program you can use it.</li></ul><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">Restriction #1 is rather easy to get around. Simply transfer the first block, and when the transfer is done, send the next block.</p><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">For those of you not familiar with pages, I'll try to explain.</p><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">Picture the first 16MB region of memory in your system. It is divided into 256 pages of 64K or 128 pages of 128K. Every page starts at a multiple of 65536 or 131072. They are numbered from 0 to 255 or from 0 to 127.</p><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">In plain English, the page is the highest 8 bits or 7 bits of the absolute 24 bit address of our memory location. The offset is the lower 16 or 17 bits of the absolute 24 bit address.</p><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">Now that we know where our data is, we need to find the length.</p><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">The DMA has a little quirk on length. The true length sent to the DMA is actually length + 1. So if you send a zero length to the DMA, it actually transfers one byte or word, whereas if you send 0xFFFF, it transfers 64K or 128K. I guess they made it this way because it would be pretty senseless to program the DMA to do nothing (a length of zero), and in doing it this way, it allowed a full 64K or 128K span of data to be transferred.</p><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">Now that you know what to send to the DMA, how do you actually start it? This enters us into the different DMA channels.</p><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">The following chart will describe each channel and it's corresponding port number:</p><table style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; "><tbody><tr><td>DMA Channel</td><td>Page</td><td>Address</td><td>Count</td></tr><tr><td>0</td><td>87h</td><td>0h</td><td>1h</td></tr><tr><td>1</td><td>83h</td><td>2h</td><td>3h</td></tr><tr><td>2</td><td>81h</td><td>4h</td><td>5h</td></tr><tr><td>3</td><td>82h</td><td>6h</td><td>7h</td></tr><tr><td>4</td><td>8Fh</td><td>C0h</td><td>C2h</td></tr><tr><td>5</td><td>8Bh</td><td>C4h</td><td>C6h</td></tr><tr><td>6</td><td>89h</td><td>C8h</td><td>CAh</td></tr><tr><td>7</td><td>8Ah</td><td>CCh</td><td>CEh</td></tr></tbody></table><p style="font-family: arial, verdana, tahoma, sans-serif; font-size: 16px; ">DMA 4. Doesn't exist. DMA 4 is used to cascade the two 8237A chips. When first 8237A wants to DMA, it issues "HRQ" to second chip's DRQ 4. The second chip thinks DMA 4 is wanna be made so issues DRQ 4 to the first chip's HLDA. First chip makes it's own DMA 0-3, then sends to the second "OK second chip, my DMA 4 is complete" and second chip knows it's free on the bus. If this mechanism would not work, the two chips could peck each other on the BUS and the PC would screw up. :+)</p></div><div>from:</div><div><a href="http://www.osdever.net/papers/view/how-does-the-dma-work">http://www.osdever.net/papers/view/how-does-the-dma-work</a></div><img src ="http://www.cppblog.com/beautykingdom/aggbug/133602.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-11-14 19:23 <a href="http://www.cppblog.com/beautykingdom/archive/2010/11/14/133602.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>理解Linux配置文件 </title><link>http://www.cppblog.com/beautykingdom/archive/2010/11/14/133601.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Sun, 14 Nov 2010 11:22:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/11/14/133601.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/133601.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/11/14/133601.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/133601.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/133601.html</trackback:ping><description><![CDATA[<pre style="word-wrap: break-word; white-space: pre-wrap; ">本文说明了 Linux 系统的配置文件，在多用户、多任务环境中，配置文件控制用户权限、系统应用程序、守护进程、服务和其它管理任务。这些任务包括管理用户帐号、分配磁盘配额、管理电子邮件和新闻组，以及配置内核参数。本文还根据配置文件的使用和其所影响的服务的情况对目前 Red Hat Linux 系统中的配置文件进行了分类。 
介绍 
每个 Linux 程序都是一个可执行文件，它含有操作码列表，CPU 将执行这些操作码来完成特定的操作。例如，ls 命令是由 /bin/ls 文件提供的，该文件含有机器指令的列表，在屏幕上显示当前目录中文件的列表时需要使用这些机器指令。几乎每个程序的行为都可以通过修改其配置文件来按照您的偏好或需要去定制。 

Linux 中有没有一个标准的配置文件格式？ 
一句话，没有。不熟悉 Linux 的用户（一定）会感到沮丧，因为每个配置文件看起来都象是一个要迎接的新挑战。在 Linux 中，每个程序员都可以自由选择他或她喜欢的配置文件格式。可以选择的格式很多，从 /etc/shells 文件（它包含被一个换行符分开的 shell 的列表），到 Apache 的复杂的 /etc/httpd.conf 文件。 

什么是系统配置文件？ 
内核本身也可以看成是一个&#8220;程序&#8221;。为什么内核需要配置文件？内核需要了解系统中用户和组的列表，进而管理文件权限（即根据权限判定特定用户（UNIX_USERS）是否可以打开某个文件）。注意，这些文件不是明确地由程序读取的，而是由系统库所提供的一个函数读取，并被内核使用。例如，程序需要某个用户的（加密过的）密码时不应该打开 /etc/passwd 文件。相反，程序应该调用系统库的 getpw() 函数。这种函数也被称为系统调用。打开 /etc/passwd 文件和之后查找那个被请求的用户的密码都是由内核（通过系统库）决定的。 

除非另行指定，Red Hat Linux 系统中大多数配置文件都在 /etc 目录中。配置文件可以大致分为下面几类： 

访问文件 
/etc/host.conf 告诉网络域名服务器如何查找主机名。（通常是 /etc/hosts，然后就是名称服务器；可通过 netconf 对其进行更改） 
/etc/hosts 包含（本地网络中）已知主机的一个列表。如果系统的 IP 不是动态生成，就可以使用它。对于简单的主机名解析（点分表示法），在请求 DNS 或 NIS 网络名称服务器之前，/etc/hosts.conf 通常会告诉解析程序先查看这里。 
/etc/hosts.allow 请参阅 hosts_access 的联机帮助页。至少由 tcpd 读取。 
/etc/hosts.deny 请参阅 hosts_access 的联机帮助页。至少由 tcpd 读取。 


引导和登录／注销 
/etc/issue &amp; /etc/issue.net 这些文件由 mingetty（和类似的程序）读取，用来向从终端（issue）或通过 telnet 会话（issue.net）连接的用户显示一个&#8220;welcome&#8221;字符串。它们包括几行声明 Red Hat 版本号、名称和内核 ID 的信息。它们由 rc.local 使用。 
/etc/redhat-release 包括一行声明 Red Hat 版本号和名称的信息。由 rc.local 使用。 
/etc/rc.d/rc 通常在所有运行级别运行，级别作为参数传送。例如，要以图形（Graphics）模式（X-Server）引导机器，请在命令行运行下面的命令：init 5。运行级别 5 表示以图形模式引导系统。 
/etc/rc.d/rc.local 非正式的。可以从 rc、rc.sysinit 或 /etc/inittab 调用。 
/etc/rc.d/rc.sysinit 通常是所有运行级别的第一个脚本。 
/etc/rc.d/rc/rcX.d 从 rc 运行的脚本（X 表示 1 到 5 之间的任意数字）。这些目录是特定&#8220;运行级别&#8221;的目录。当系统启动时，它会识别要启动的运行级别，然后调用该运行级别的特定目录中存在的所有启动脚本。例如，系统启动时通常会在引导消息之后显示&#8220;entering run-level 3&#8221;的消息；这意味着 /etc/rc.d/rc3.d/ 目录中的所有初始化脚本都将被调用。 


文件系统 
内核提供了一个接口，用来显示一些它的数据结构，这些数据结构对于决定诸如使用的中断、初始化的设备和内存统计信息之类的系统参数可能很有用。这个接口是作为一个独立但虚拟的文件系统提供的，称为 /proc 文件系统。很多系统实用程序都使用这个文件系统中存在的值来显示系统统计信息。例如，/proc/modules 文件列举系统中当前加载的模块。lsmod 命令读取此信息，然后将其以人们可以看懂的格式显示出来。下面表格中指定的 mtab 文件以同样的方式读取包含当前安装的文件系统的 /proc/mount 文件。 /etc/mtab 这将随着 /proc/mount 文件的改变而不断改变。换句话说，文件系统被安装和卸载时，改变会立即反映到此文件中。 
/etc/fstab 列举计算机当前&#8220;可以安装&#8221;的文件系统。这非常重要，因为计算机引导时将运行 mount -a 命令，该命令负责安装 fstab 的倒数第二列中带有&#8220;1&#8221;标记的每一个文件系统。 
/etc/mtools.conf DOS 类型的文件系统上所有操作（创建目录、复制、格式化等等）的配置。 


系统管理 
/etc/group 包含有效的组名称和指定组中包括的用户。单一用户如果执行多个任务，可以存在于多个组中。例如，如果一个&#8220;用户&#8221;是&#8220;project 1&#8221;工程组的成员，同时也是管理员，那么在 group 文件中他的条目看起来就会是这样的：user: * : group-id : project1 
/etc/nologin 如果有 /etc/nologin 文件存在，login(1) 将只允许 root 用户进行访问。它将对其它用户显示此文件的内容并拒绝其登录。 
/etc/passwd 请参阅&#8220;man passwd&#8221;。它包含一些用户帐号信息，包括密码（如果未被 shadow 程序加密过）。 
/etc/rpmrc rpm 命令配置。所有的 rpm 命令行选项都可以在这个文件中一起设置，这样，当任何 rpm 命令在该系统中运行时，所有的选项都会全局适用。 
/etc/securetty 包含设备名称，由 tty 行组成（每行一个名称，不包括前面的 /dev/），root 用户在这里被允许登录。 
/etc/usertty 
/etc/shadow 包含加密后的用户帐号密码信息，还可以包括密码时效信息。包括的字段有： 
登录名 
加密后的密码 
从 1970 年 1 月 1 日到密码最后一次被更改的天数 
距密码可以更改之前的天数 
距密码必须更改之前的天数 
密码到期前用户被警告的天数 
密码到期后帐户被禁用的天数 
从 1970 年 1 月 1 日到帐号被禁用的天数 

/etc/shells 包含系统可用的可能的&#8220;shell&#8221;的列表。 
/etc/motd 每日消息；在管理员希望向 Linux 服务器的所有用户传达某个消息时使用。 


联网 
/etc/gated.conf gated 的配置。只能被 gated 守护进程所使用。 
/etc/gated.version 包含 gated 守护进程的版本号。 
/etc/gateway 由 routed 守护进程可选地使用。 
/etc/networks 列举从机器所连接的网络可以访问的网络名和网络地址。通过路由命令使用。允许使用网络名称。 
/etc/protocols 列举当前可用的协议。请参阅 NAG（网络管理员指南，Network Administrators Guide）和联机帮助页。 
C 接口是 getprotoent。绝不能更改。 
/etc/resolv.conf 在程序请求&#8220;解析&#8221;一个 IP 地址时告诉内核应该查询哪个名称服务器。 
/etc/rpc 包含 RPC 指令／规则，这些指令／规则可以在 NFS 调用、远程文件系统安装等中使用。 
/etc/exports 要导出的文件系统（NFS）和对它的权限。 
/etc/services 将网络服务名转换为端口号／协议。由 inetd、telnet、tcpdump 和一些其它程序读取。有一些 C 访问例程。 
/etc/inetd.conf inetd 的配置文件。请参阅 inetd 联机帮助页。包含每个网络服务的条目，inetd 必须为这些网络服务控制守护进程或其它服务。注意，服务将会运行，但在 /etc/services 中将它们注释掉了，这样即使这些服务在运行也将不可用。格式为： 
/etc/sendmail.cf 邮件程序 sendmail 的配置文件。比较隐晦，很难理解。 
/etc/sysconfig/network 指出 NETWORKING=yes 或 no。至少由 rc.sysinit 读取。 
/etc/sysconfig/network-scripts/if* Red Hat 网络配置脚本。 


系统命令 
系统命令要独占地控制系统，并让一切正常工作。所有如 login（完成控制台用户身份验证阶段）或 bash（提供用户和计算机之间交互）之类的程序都是系统命令。因此，和它们有关的文件也特别重要。这一类别中有下列令用户和管理员感兴趣的文件。 /etc/lilo.conf 包含系统的缺省引导命令行参数，还有启动时使用的不同映象。您在 LILO 引导提示的时候按 Tab 键就可以看到这个列表。 
/etc/logrotate.conf 维护 /var/log 目录中的日志文件。 
/etc/identd.conf identd 是一个服务器，它按照 RFC 1413 文档中指定的方式实现 TCP/IP 提议的标准 IDENT 用户身份识别协议。identd 的操作原理是查找特定 TCP/IP 连接并返回拥有此连接的进程的用户名。作为选择，它也可以返回其它信息，而不是用户名。请参阅 identd 联机帮助页。 
/etc/ld.so.conf &#8220;动态链接程序&#8221;（Dynamic Linker）的配置。 
/etc/inittab 按年代来讲，这是 UNIX 中第一个配置文件。在一台 UNIX 机器打开之后启动的第一个程序是 init，它知道该启动什么，这是由于 inittab 的存在。在运行级别改变时，init 读取 inittab，然后控制主进程的启动。 
/etc/termcap 一个数据库，包含所有可能的终端类型以及这些终端的性能。 


守护进程 
守护进程是一种运行在非交互模式下的程序。一般来说，守护进程任务是和联网区域有关的：它们等待连接，以便通过连接提供服务。Linux 可以使用从 Web 服务器到 ftp 服务器的很多守护进程。 /etc/syslogd.conf syslogd 守护进程的配置文件。syslogd 是一种守护进程，它负责记录（写到磁盘）从其它程序发送到系统的消息。这个服务尤其常被某些守护进程所使用，这些守护进程不会有另外的方法来发出可能有问题存在的信号或向用户发送消息。 

/etc/httpd.conf Web 服务器 Apache 的配置文件。这个文件一般不在 /etc 中。它可能在 /usr/local/httpd/conf/ 或 /etc/httpd/conf/ 中，但是要确定它的位置，您还需要检查特定的 Apache 安装信息。 
/etc/conf.modules or /etc/modules.conf kerneld 的配置文件。有意思的是，kerneld 并不是&#8220;作为守护进程的&#8221;内核。它其实是一种在需要时负责&#8220;快速&#8221;加载附加内核模块的守护进程。 


用户程序 
在 Linux（和一般的 UNIX）中，有无数的&#8220;用户&#8221;程序。最常见的一种用户程序配置文件是 /etc/lynx.cfg。这是著名的文本浏览器 lynx 的配置文件。通过这个文件，您可以定义代理服务器、要使用的字符集等等。下面的代码样本展示了 lynx.cfg 文件的一部分，修改这部分代码可以改变 Linux 系统的代理服务器设置。缺省情况下，这些设置适用于在各自的 shell 中运行 lynx 的所有用户，除非某个用户通过指定 --cfg = "mylynx.cfg" 重设了缺省的配置文件。 

/etc/lynx.cfg 中的代理服务器设置 
.h1 proxy 
.h2 HTTP_PROXY 
.h2 HTTPS_PROXY 
.h2 FTP_PROXY 
.h2 GOPHER_PROXY 
.h2 NEWS_PROXY 
.h2 NNTP_PROXY 
# Lynx version 2.2 and beyond supports the use of proxy servers that can act as 
# firewall gateways and caching servers. They are preferable to the older 
# gateway servers. Each protocol used by Lynx can be mapped separately using 
# PROTOCOL_proxy environment variables (see Lynx Users Guide). If you have 
# not set them externally, you can set them at run time via this configuration file. 
# They will not override external settings. The no_proxy variable can be used 
# to inhibit proxying to selected regions of the Web (see below). Note that on 
# VMS these proxy variables are set as process logicals rather than symbols, to 
# preserve lowercasing, and will outlive the Lynx image. 
# 
.ex 15 
http_proxy:http://proxy3.in.ibm.com:80/ 
ftp_proxy:http://proxy3.in.ibm.com:80/ 
#http_proxy:http://penguin.in.ibm.com:8080 
#ftp_proxy:http://penguin.in.ibm.com:8080/ 

.h2 NO_PROXY 
# The no_proxy variable can be a comma-separated list of strings defining 
# no-proxy zones in the DNS domain name space. If a tail substring of the 
# domain-path for a host matches one of these strings, transactions with that 
# node will not be proxied. 
.ex 
no_proxy:demiurge.in.ibm.com, demiurge 





更改配置文件 
在更改配置文件时，如果程序不是由系统管理员或内核控制的，就要确保重新启动过使用该配置的程序。普通用户通常没有启动或停止系统程序和／或守护进程的权限。 

内核 
更改内核中的配置文件会立即影响到系统。例如，更改 passwd 文件以增加用户将立即使该用户变为可用。而且任何 Linux 系统的 /proc/sys 目录中都有一些内核可调参数。只有超级用户可以得到对所有这些文件的写访问权力；其它用户只有只读访问权力。此目录中文件的分类的方式和 Linux 内核源代码的分类方式一样。此目录中的每个文件都代表一个内核数据结构，这些数据结构可以被动态地修改，从而改变系统性能。 

注意：在更改其中任何文件的任何值之前，您应该确保自己全面了解该文件，以避免对系统造成不可修复的损害。 
/proc/sys/kernel/ 目录中的文件 文件名 描述 
threads-max 内核可运行的最大任务数。 
ctrl-alt-del 如果值为 1，那么顺序按下这几个键将&#8220;彻底地&#8221;重新引导系统。 
sysrq 如果值为 1，Alt-SysRq 则为激活状态。 
osrelease 显示操作系统的发行版版本号 
ostype 显示操作系统的类型。 
hostname 系统的主机名。 
domainname 网络域，系统是该网络域的一部分。 
modprobe 指定 modprobe 是否应该在启动时自动运行并加载必需的模块。 


守护进程和系统程序 
守护进程是永远运行在后台的程序，它默默地执行自己的任务。常见的守护进程有 in.ftpd（ftp 服务器守护进程）、in.telnetd（telnet 服务器守护进程）和 syslogd（系统日志记录守护进程）。有些守护进程在运行时会严密监视配置文件，在配置文件改变时就会自动重新加载它。但是大多数守护进程并不会自动重新加载配置文件。我们需要以某种方式&#8220;告诉&#8221;这些守护进程配置文件已经被发生了改变并应该重新加载。可以通过使用服务命令重新启动服务来达到这个目的（在 Red Hat Linux 系统上）。 

例如，如果我们更改了网络配置，就需要发出： 
service network restart。 

注意：这些服务最常见的是 /etc/rc.d/init.d/* 目录中存在的脚本，在系统被引导时由 init 启动。所以，您也可以执行如下操作来重新启动服务： 
/etc/rc.d/init.d/ start | stop | status 
start、stop 和 status 是这些脚本接受的输入值，用来执行操作。 

用户程序 
用户或系统程序在每次启动时都会读取其配置文件。尽管如此，请记住，有些系统程序在计算机打开时情况不一样，它们的行为依赖于在 /etc/ 中的配置文件中读到的内容。所以，用户程序第一次启动时将从 /etc/ 目录中存在的文件读取缺省配置。然后，用户可以通过使用 rc 和 .（点）文件来定制程序，正如下面一节所示。 

用户配置文件：.（点）文件和 rc 文件 
我们已经看到怎样容易地配置程序。但是如果有的人不喜欢在 /etc/ 中配置程序的方式该怎么办呢？&#8220;普通&#8221;用户不能简单地进入 /etc 然后更改配置文件；从文件系统的角度来看，配置文件的所有者是 root 用户！这就是大多数用户程序都定义两个配置文件的原因：第一个是&#8220;系统&#8221;级别的，位于 /etc/；另一个属于用户&#8220;专用&#8221;，可以在他或她的主目录中找到。 

例如，我在我的系统中安装了非常有用的 wget 实用程序。/etc/ 中有一个 /etc/wgetrc 文件。在我的主目录中，有一个名为 .wgetrc 的文件，它描述了我定制的配置（只有在我，也就是用户运行 wget 命令时，才会加载这个配置文件）。其它用户在他们自己的主目录（/home/other）中也可以有 .wgetrc 文件；当然，只有这些用户运行 wget 命令时，才会读取这个文件。换句话说，/etc/wgetrc 文件为 wget 提供了&#8220;缺省&#8221;值，而 /home/xxx/.wgetrc 文件列举了某个用户的&#8220;定制项&#8221;。重要的是这只是&#8220;一般规则&#8221;，并非所有情况都如此。例如，一个象 pine 一样的程序，在 /etc/ 中并没有任何文件，它只在用户主目录中有一个定制配置文件，名为 .pinerc。其它程序可能只有 /etc/ 中的缺省配置文件，而且可能不允许用户&#8220;定制&#8221;这些配置文件（/etc 目录中只有少数 config. 文件是这种情况）。 

通常使用的 rc 和 .（点）文件 
文件名 描述 
~/.bash_login 请参考&#8220;man bash&#8221;。如果 ~/.bash_profile 不存在，bash 则将 ~/.bash_login 作为 ~/.bash_profile 处理。 
~/.bash_logout 请参考&#8220;man bash&#8221;。在退出时由 bash 登录 shell 引用。 
~/.bash_profile 由 bash 登录 shell 引用 /etc/profile 之后引用。 
~/.bash_history 先前执行的命令的列表。 
~/.bashrc 请参考&#8220;man bash&#8221;。由 bash 非登录交互式 shell 引用（没有其它文件）。除非设置了 BASH_ENV 或 ENV，非交互式 shell 不引用任何文件。 
~/.emacs 启动时由 emac 读取。 
~/.forward 如果这里包含一个电子邮件地址，那么所有发往 ~ 的所有者的邮件都会被转发到这个电子邮件地址。 
~/.fvwmrc ~/.fvwm2rc fvwm 和 fvwm2（基本的 X Window 管理器）的配置文件。 
~/.hushlogin 请参考&#8220;man login&#8221;。引起&#8220;无提示&#8221;登录（没有邮件通知、上次登录信息或者 MOD 信息）。 
~/.mail.rc 邮件程序的用户初始化文件。 
~/.ncftp/ ncftp 程序的目录；包含书签、日志、宏、首选项和跟踪信息。请参阅 man ncftp。ncftp 的目的是为因特网标准文件传输协议（Internet standard File Transfer Protocol）提供一个强大而灵活的接口。它旨在替换系统所使用的标准的 ftp 程序。 
~/.profile 请参考&#8220;man bash&#8221;。如果 ~/.bash_profile 和 ~/.bash_login 文件不存在，bash 则将 ~/.profile 作为 ~/.bash_profile 处理，并被其它继承 Bourn 的 shell 使用。 
~/.pinerc Pine 配置 
~/.muttrc Mutt 配置 
~/.exrc 这个文件可以控制 vi 的配置。 
示例：set ai sm ruler 
在此文件中写入上面一行会让 vi 设置自动缩进、匹配括号、显示行号和行-列这几个选项。 
~/.vimrc 缺省的&#8220;Vim&#8221;配置文件。和 .exrc 一样。 
~/.gtkrc GNOME 工具包（GNOME Toolkit）。 
~/.kderc KDE 配置。 
~/.netrc ftp 缺省登录名和密码。 
~/.rhosts 由 r- 工具（如 rsh、rlogin 等等）使用。因为冒充主机很容易，所以安全性非常低。 
必须由用户（~/ 的所有者）或超级用户拥有。 
列出一些主机，用户可以从这些主机访问该帐号。 
如果是符号链接则被忽略。 

~/.rpmrc 请参阅&#8220;man rpm&#8221;。如果 /etc/rpmrc 不存在则由 rpm 读取。 
~/.signature 消息文本，将自动附加在从此帐号发出的邮件末尾。 
~/.twmrc twm（The Window Manager）的配置文件。 
~/.xinitrc 启动时由 X 读取（而不是由 xinit 脚本读取）。通常会启动一些程序。 
示例：exec /usr/sbin/startkde 
如果该文件中存在上面这行内容，那么在从这个帐号发出 startx 命令时，这一行就会启动&#8220;KDE 视窗管理器&#8221;（KDE Window Manager）。 
~/.xmodmaprc 此文件被传送到 xmodmap 程序，而且可以被命名为任何文件（例如 ~/.Xmodmap 和 ~/.keymap.km）。 
~/.xserverrc 如果 xinit 可以找到要执行的 X，xinit 就会将该文件作为 X 服务器运行。 
~/News/Sent-Message-IDs gnus 的缺省邮件历史文件。 
~/.Xauthority 由 xdm 程序读和写，以处理权限。请参阅 X、xdm 和 xauth 联机帮助页。 
~/.Xdefaults, 
~/.Xdefaults-hostname 在主机 hostname 的启动过程中由 X 应用程序读取。如果找不到 -hostname 文件，则查找 .Xdefaults 文件。 
~/.Xmodmap 指向 .xmodmaprc；Red Hat 有使用这个名称的 .xinitrc 文件。 
~/.Xresources 通常是传送到 xrdb 以加载 X 资源数据库的文件的名称，旨在避免应用程序需要读取一个很长的 .Xdefaults 文件这样的情况。（有些情况曾经使用了 ~/.Xres。） 

~/mbox 用户的旧邮件。 


参考资料 

要了解更多信息，请阅读 Jack Wallen, Jr. 的 Linux configuration files。 


在 developerWorks 上还有： 
Technical FAQ for Linux users 
What good is a Linux client? 
Using the xinetd program for system administration 


流览 developerWorks 上的更多 Linux 参考资料。 


流览 developerWorks 上的更多开放源代码参考资料。 

关于作者 
Subodh Soni 持有印度 College Surat 大学计算机科学与技术地区工程学的工程学学士学位。他为印度的 IBM Global Services（IBM Software Labs）工作；他还是 IBM Linux Technology Center 的成员之一，在那里他致力于 Linux RAS（Reliability，Availability and Serviceability（可靠性、可用性和适用性））。他感兴趣的其它领域还有操作系统内部、Linux 系统管理和疑难解答。您可以通过 subodh@in.ibm.com 与他联系。 

</pre><pre style="word-wrap: break-word; white-space: pre-wrap; "><br></pre><pre style="word-wrap: break-word; white-space: pre-wrap; ">from: ibm developerworks</pre>
<img src ="http://www.cppblog.com/beautykingdom/aggbug/133601.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-11-14 19:22 <a href="http://www.cppblog.com/beautykingdom/archive/2010/11/14/133601.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>网络配置文件快速解读</title><link>http://www.cppblog.com/beautykingdom/archive/2010/11/14/133600.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Sun, 14 Nov 2010 11:20:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/11/14/133600.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/133600.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/11/14/133600.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/133600.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/133600.html</trackback:ping><description><![CDATA[<pre style="word-wrap: break-word; white-space: pre-wrap; ">iamafan 


在Linux系统中，TCP/IP网络是通过若干个文本文件进行配置的，需要编辑这些文件来完成联网工作。系统中重要的有关网络配置文件为： 

◆ /etc/sysconfig/network 
◆ /etc/HOSTNAME 
◆ /etc/hosts 
◆ /etc/services 
◆ /etc/host.conf 
◆ /etc/nsswitch.conf 
◆ /etc/resolv.conf 
◆ /etc/rc.d/init.d/network 

接下来我们将对这些文件逐一讲述，这些文件都可以在系统运行时进行修改，不用启动或者停止任何守护程序，更改会立刻生效(除了/etc/sysconfig/network)。另外，这些文件都支持由"#"开头的注释，每一个文件都有在UNIX手册页中的第5部分中有一项，可以用man命令来获取它们。 

◆ /etc/sysconfig/network 网络设置 
该文件用来指定服务器上的网络配置信息，包含了控制和网络有关的文件和守护程序的行为的参数。下面是一个例子文件： 

NETWORKING=yes 
HOSTNAME=machine1 
GATEWAY=210.34.6.2 
FORWARD_IPV4=yes 
GATEWAYDEV= 

其中，NETWORK=yes/no 表示网络是否被配置； 
HOSTNAME=hostname hostname 表示服务器的主机名； 
GATEWAY=gw-ip gw-ip 表示网络网关的IP地址； 
FORWARD_IPV4=yes/no 是否开启IP转发功能； 
GAREWAYDEV=gw-dev gw-dw 表示网关的设备名，如：eth0等； 
为了和老的一些软件相兼容，"/etc/HOSTNAME"文件应该用和HOSTNAME=hostname相同的主机名。 

◆ /etc/HOSTNAME 主机名 

该文件包含了系统的主机名称，包括完全的域名，如： 

192.168.0.1 machine1.domain machine1 

这个文件是在启动时从文件/etc/sysconfig/network中的HOSTNAME行中得到的，用于在启动时设置系统的主机名。 

◆ /etc/hosts IP地址和主机名的映射 

/etc/hosts中包含了IP地址和主机名之间的映射，还包括主机名的别名，IP地址的设计使计算机容易识别，但对于人却很难记住它们，为了解决这个问题，创建了/etc/hosts这个文件。下面是一个例子文件： 

127.0.0.1 machine1 localhost.localdomain localhost 
192.168.1.100 machine7 
192.168.1.101 otherpc otheralias 

在这个例子中，本机名是machine1，otherpc还有别名otheralias，它可以指向otheralias。。一旦配置完机器的网络配置文件，应该重新启动网络以使修改生效，使用下面的命令来重新启动网络： 

/etc/rc.d/init.d/network restart 

/etc/hosts文件通常含有主机名、localhost和系统管理员经常使用的系统别名，有时候telnet到Linux机器要等待很长时间，可以通过在"/etc/hosts"加入客户的机器的IP地址和主机名的匹配项，就可以减少登录等待时间。在没有域名服务器情况下，系统上的所有网络程序都通过查询该文件来解析对应于某个主机名的IP地址，否则，其他的主机名通常使用DNS来解决，DNS客户部分的配置在文件/etc/resolv.conf中。 

◆ /etc/services 

/etc/services中包含了服务名和端口号之间的映射，不少的系统程序要使用这个文件，下面是RedHat 安装时缺省的/etc/services中的前几行： 

tcpmux 1/tcp # TCP port service multiplexer 
echo 7/tcp 
echo 7/udp 
discard 9/tcp sink null 
discard 9/udp sink null 
systat 11/tcp users 

最左边一列是主机服务名，中间一列是端口号，&#8221;/&#8220; 后面是端口类型，可以是TCP也可以是UDP。任何后面的列都是前面服务的别名。在这个文件中也存在着别名，它们出现在端口号后面，在上述例子中sink和null 都是discard服务的别名。 

◆ /etc/host.conf 配置名字解析器 

有两个文件声明系统到哪里寻找名字信息来配置UNIX名字解析器的库。文件/etc/host.conf由版本5的libc库所使用，而/etc/nsswitch.conf由版本6使用(glibc )。问题在于一些程序使用其中一个，而一些使用另一个，所以将两个文件都配置正确是必要的。 

/etc/host.conf文件指定如何解析主机名，Linux通过解析器库来获得主机名对应的IP地址。下面是RedHat安装后缺省的"/etc/host.conf"内容： 

order hosts，bind 
multi on 

※"order " 指定主机名查询顺序，其参数为用逗号隔开的查找方法，支持的查找方法为bind、hosts和nis，分别代表DNS、/etc/hosts和NIS，这里规定先查询"/etc/hosts"文件然后再使用DNS来解析域名。 
※"trim" 表明当通过DNS进行地址到主机名的转换时，域名将从主机名中被裁剪掉，trim可以被多个域包含多次，对/etc/hosts和NIS查询方法不起作用，注意在/etc/hosts和NIS表中主机名是被适当地(有或没有全域名)列出的。 
※"multi" 指定是否"/etc/hosts"文件中指定的主机可以有多个地址，值为on表示允许，拥有多个IP地址的主机一般称为具有多个网络界面。 
※"nospoof " 指是否允许对该服务器进行IP地址欺骗，值为on表示不允许，IP欺骗是一种攻击系统安全的手段，通过把IP地址伪装成别的计算机，来取得其它计算机的信任。 
※"alert" 当nospoof指令为on时，alert控制欺骗的企图是否用syslog工具进行记录，值为on表示使用，缺省值为off。 
※"rccorder" 如果被设置为on，所有的查询将被重新排序，所以在同一子网中的主机将首选被返回，缺省值为off。 

◆ /etc/nsswitch.conf 配置名字解析器 

/etc/nsswitch.conf文件是由S u n公司开发并用于管理系统中多个配置文件查找的顺序，它比/etc/host.conf文件提供了更多的功能。/etc/nsswitch.conf中的每一行或者是注释(以#号开头)或者是一个关键字后跟冒号和一系列要试用的有顺序的方法。每一个关键字是在/etc/目录可以被/etc/nsswitch.conf控制的/etc文件的名字。下面是可以被包含的关键字： 

※aliases 邮件别名； 
※passwd 系统用户； 
※group 用户组； 
※shadow 隐蔽口令； 
※hosts 主机名和I P地址； 
※networks 网络名和号； 
※protocols 网络协议； 
※services 端口号和服务名称； 
※ethers 以太网号； 
※rpc 远程进程调用的名称和号 
※netgroup 网内组 

下面也是可以包含的关键字： 

※files 除了netgroup，对其他关键字都有效。在相应的/etc文件中寻找记录 
※db 除了netgroup，对其他关键字都有效。在相应的/var/db数据库中寻找记录。对长文件很有效，如passwd文件已经 超过500项。要从标准/etc文件中产生这些文件，应改变目录到/var/db并运行run命令 
※compat 兼容性模式，对passwd、group和shadow文件有效。在本模式中，将先在对应的/etc文件中查找。如果想进行NIS查找，需要第一个值(用户名或组名)为加号( + )，后面跟对应数量的冒号( : ) ( /etc/passwd为6个， /etc/group为3个， /etc/shadow为8个)。如在/etc/passwd文件中，下面一行应被包含在文件尾： + : * : : : : : 
※dns 只对hosts有意义。像在/etc/resolvconf配置的，在DNS中进行查找 
※nis 对所有的关键字都有意义。如NIS是可以用的，在NIS服务器中查找 
※[ STATUS = action ] 控制名字服务的行为。STATUS是SUCCESS(操作被成功执行)、NOTFOUND (记录没找到)、UNAVAIL (所选择的服务不可用)和TRYAGAIN (服务暂时不可用，请重试)中的一个。action是return (终止查找并返回当前状态)或continue (继续这一行的其他项)中的一个。如hosts: dns nis [NOTFOUND=return] files将会首先在DNS中，然后在NIS中查找主机名。只有当前两项都不可用时才使用文件/etc/hosts 

◆ /etc/resolv.conf 配置DNS客户 

文件/etc/resolv.conf配置DNS客户，它包含了主机的域名搜索顺序和DNS服务器的地址，每一行应包含一个关键字和一个或多个的由空格隔开的参数。下面是一个例子文件： 

search mydom.edu.cn 
nameserver 210.34.0.14 
nameserver 210.34.0.2 

合法的参数及其意义如下： 
※nameserver 表明DNS服务器的IP地址。可以有很多行的nameserver，每一个带一个I P地址。在查询时就按nameserver在本文件中的顺序进行，且只有当第一个nameserver没有反应时才查询下面的nameserver. 
※domain 声明主机的域名。很多程序用到它，如邮件系统；当为没有域名的主机进行DNS查询时，也要用到。如果没有域名，主机名将被使用，删除所有在第一个点( . )前面的内容。 
※search 它的多个参数指明域名查询顺序。当要查询没有域名的主机，主机将在由search声明的域中分别查找。domain和search不能共存；如果同时存在，后面出现的将会被使用。 
※sortlist 允许将得到域名结果进行特定的排序。它的参数为网络/掩码对，允许任意的排列顺序。Red Hat中没有提供缺省的/ e t c / r e s o l v. c o n f文件，它的内容是根据在安装时给出的选项动态创建的。 

◆ /etc/init.d/network 主机地址、子网掩码和网关 

不像很多其他的UNIX和Linux操作系统， Red Hat当前并不能自动地通过/etc/hostname和/etc/hosts文件来配置网络。为了改变主机缺省的IP地址，必须直接编辑/etc/init.d/network脚本使其反映正确的网络配置。这个文件包括了声明IP地址、掩码、网络、广播地址和缺省路由器的变量。下面是这个文件中相应的部分： 

IPADDR=192.168.1.100 
NETMASK=255.255.255.0 
BROADCAST=192.168.1.255 
GATEWAY=192.168.1.1  </pre>
<img src ="http://www.cppblog.com/beautykingdom/aggbug/133600.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-11-14 19:20 <a href="http://www.cppblog.com/beautykingdom/archive/2010/11/14/133600.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux 引导过程内幕 从主引导记录到第一个用户空间应用程序的指导</title><link>http://www.cppblog.com/beautykingdom/archive/2010/11/08/133023.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Mon, 08 Nov 2010 11:58:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/11/08/133023.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/133023.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/11/08/133023.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/133023.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/133023.html</trackback:ping><description><![CDATA[

<span style="font-family: arial, nsimsun, sans-serif; font-size: 12px; "><strong style="font-size: 1em; font-weight: bold; ">简介：</strong></span><span style="font-family: arial, nsimsun, sans-serif; font-size: 12px; ">&nbsp;引导 Linux&#174; 系统的过程包括很多阶段。不管您是引导一个标准的 x86 桌面系统，还是引导一台嵌入式的 PowerPC&#174; 机器，很多流程都惊人地相似。本文将探索 Linux 的引导过程，从最初的引导到启动第一个用户空间应用程序。在本文介绍的过程中，您将学习到各种与引导有关的主题，例如引导加载程序、内核解压、初始 RAM 磁盘以及 Linux 引导的其他一些元素。</span>

<div><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; ">早期时，启动一台计算机意味着要给计算机喂一条包含引导程序的纸带，或者手工使用前端面板地址/数据/控制开关来加载引导程序。尽管目前的计算机已经装备了很多工具来简化引导过程，但是这一切并没有对整个过程进行必要的简化。</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; ">让我们先从高级的视角来查看 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; "><a name="N1005E"><span class="atitle" 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; ">图 1 是我们在 20,000 英尺的高度看到的视图。</p><br><a name="fig1" style="font-family: Simsun; 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. Linux 引导过程在 20,000 英尺处的视图</strong></a><br><span style="border-style: initial; border-color: initial; padding-top: 0.3em; padding-bottom: 0.7em;"><img alt="Linux 引导过程在 20,000 英尺处的视图" height="300" src="http://www.ibm.com/developerworks/cn/linux/l-linuxboot/fig1.gif" width="529" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; "></span>&nbsp;<br><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; ">当系统首次引导时，或系统被重置时，处理器会执行一个位于已知位置处的代码。在个人计算机（PC）中，这个位置在基本输入/输出系统（BIOS）中，它保存在主板上的闪存中。嵌入式系统中的中央处理单元（CPU）会调用这个重置向量来启动一个位于闪存/ROM 中的已知地址处的程序。在这两种情况下，结果都是相同的。因为 PC 提供了很多灵活性，BIOS 必须确定要使用哪个设备来引导系统。稍后我们将详细介绍这个过程。</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; ">当找到一个引导设备之后，第一阶段的引导加载程序就被装入 RAM 并执行。这个引导加载程序在大小上小于 512 字节（一个扇区），其作用是加载第二阶段的引导加载程序。</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; ">当第二阶段的引导加载程序被装入 RAM 并执行时，通常会显示一个动画屏幕，并将 Linux 和一个可选的初始 RAM 磁盘（临时根文件系统）加载到内存中。在加载映像时，第二阶段的引导加载程序就会将控制权交给内核映像，然后内核就可以进行解压和初始化了。在这个阶段中，第二阶段的引导加载程序会检测系统硬件、枚举系统链接的硬件设备、挂载根设备，然后加载必要的内核模块。完成这些操作之后启动第一个用户空间程序（<code style="font-family: monospace; font-size: small !important; ">init</code>），并执行高级系统初始化工作。</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; ">这就是 Linux 引导的整个过程。现在让我们深入挖掘一下这个过程，并深入研究一下 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; "><span style="font-family: Simsun; font-size: medium; "></span></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; "><a name="N10087"><span class="atitle" 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; ">系统启动阶段依赖于引导 Linux 系统上的硬件。在嵌入式平台中，当系统加电或重置时，会使用一个启动环境。这方面的例子包括 U-Boot、RedBoot 和 Lucent 的 MicroMonitor。嵌入式平台通常都是与引导监视器搭配销售的。这些程序位于目标硬件上的闪存中的某一段特殊区域，它们提供了将 Linux 内核映像下载到闪存并继续执行的方法。除了可以存储并引导 Linux 映像之外，这些引导监视器还执行一定级别的系统测试和硬件初始化过程。在嵌入式平台中，这些引导监视器通常会涉及第一阶段和第二阶段的引导加载程序。</p><div class="ibm-container ibm-alt-header dw-container-sidebar" style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.2em; margin-left: 10px; width: 320px; float: right; "><h2 style="font-family: arial, nsimsun, sans-serif; background-image: none; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 248, 252); border-top-color: rgb(204, 204, 204); border-right-color: rgb(204, 204, 204); border-bottom-color: rgb(204, 204, 204); border-left-color: rgb(204, 204, 204); border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 3px; padding-right: 5px; padding-bottom: 3px; padding-left: 5px; height: 15px; font-size: 0.75em; background-position: 0px -545px; background-repeat: repeat no-repeat; ">提取 MBR 的信息</h2><div class="ibm-container-body" style="background-image: url(http://www.ibm.com/i/v16/t/container-gradient.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(255, 255, 255); border-left-color: rgb(204, 204, 204); font-size: 0.76em; font-family: arial, sans-serif; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; background-position: 0px 100%; background-repeat: repeat no-repeat; "><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; ">要查看 MBR 的内容，请使用下面的命令：</p><code style="font-family: monospace; font-size: small !important; ">#&nbsp;<strong>dd if=/dev/hda of=mbr.bin bs=512 count=1</strong>&nbsp;#<strong>od -xa mbr.bin</strong></code><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; ">这个&nbsp;<code style="font-family: monospace; font-size: small !important; ">dd</code>&nbsp;命令需要以 root 用户的身份运行，它从 /dev/hda（第一个 IDE 盘） 上读取前 512 个字节的内容，并将其写入&nbsp;<code style="font-family: monospace; font-size: small !important; ">mbr.bin</code>&nbsp;文件中。<code style="font-family: monospace; font-size: small !important; ">od</code>&nbsp;命令会以十六进制和 ASCII 码格式打印这个二进制文件的内容。</p></div></div><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; ">在 PC 中，引导 Linux 是从 BIOS 中的地址 0xFFFF0 处开始的。BIOS 的第一个步骤是加电自检（POST）。POST 的工作是对硬件进行检测。BIOS 的第二个步骤是进行本地设备的枚举和初始化。</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; ">给定 BIOS 功能的不同用法之后，BIOS 由两部分组成：POST 代码和运行时服务。当 POST 完成之后，它被从内存中清理了出来，但是 BIOS 运行时服务依然保留在内存中，目标操作系统可以使用这些服务。</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; ">要引导一个操作系统，BIOS 运行时会按照 CMOS 的设置定义的顺序来搜索处于活动状态并且可以引导的设备。引导设备可以是软盘、CD-ROM、硬盘上的某个分区、网络上的某个设备，甚至是 USB 闪存。</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; ">通常，Linux 都是从硬盘上引导的，其中主引导记录（MBR）中包含主引导加载程序。MBR 是一个 512 字节大小的扇区，位于磁盘上的第一个扇区中（0 道 0 柱面 1 扇区）。当 MBR 被加载到 RAM 中之后，BIOS 就会将控制权交给 MBR。</p><p>&#160;</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; "><span style="font-family: Simsun; font-size: medium; "></span></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; "><a name="N100C2"><span class="atitle" 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; ">MBR 中的主引导加载程序是一个 512 字节大小的映像，其中包含程序代码和一个小分区表（参见图 2）。前 446 个字节是主引导加载程序，其中包含可执行代码和错误消息文本。接下来的 64 个字节是分区表，其中包含 4 个分区的记录（每个记录的大小是 16 个字节）。MBR 以两个特殊数字的字节（0xAA55）结束。这个数字会用来进行 MBR 的有效性检查。</p><br><a name="fig2"><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. MBR 剖析</strong></a><br><img alt="MBR 剖析" height="469" src="http://www.ibm.com/developerworks/cn/linux/l-linuxboot/fig2.gif" width="479" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; ">&nbsp;<br><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; ">主引导加载程序的工作是查找并加载次引导加载程序（第二阶段）。它是通过在分区表中查找一个活动分区来实现这种功能的。当找到一个活动分区时，它会扫描分区表中的其他分区，以确保它们都不是活动的。当这个过程验证完成之后，就将活动分区的引导记录从这个设备中读入 RAM 中并执行它。</p><p>&#160;</p><p style="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; "></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; "><a name="N100DE"><span class="atitle" 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; ">次引导加载程序（第二阶段引导加载程序）可以更形象地称为内核加载程序。这个阶段的任务是加载 Linux 内核和可选的初始 RAM 磁盘。</p><div class="ibm-container ibm-alt-header dw-container-sidebar" style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.2em; margin-left: 10px; width: 320px; float: right; font-family: Simsun; font-size: medium; "><h2 style="font-family: arial, nsimsun, sans-serif; background-image: none; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 248, 252); border-top-color: rgb(204, 204, 204); border-right-color: rgb(204, 204, 204); border-bottom-color: rgb(204, 204, 204); border-left-color: rgb(204, 204, 204); border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 3px; padding-right: 5px; padding-bottom: 3px; padding-left: 5px; height: 15px; font-size: 0.75em; background-position: 0px -545px; background-repeat: repeat no-repeat; ">GRUB 阶段引导加载程序</h2><div class="ibm-container-body" style="background-image: url(http://www.ibm.com/i/v16/t/container-gradient.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(255, 255, 255); border-left-color: rgb(204, 204, 204); font-size: 0.76em; font-family: arial, sans-serif; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; background-position: 0px 100%; background-repeat: repeat no-repeat; "><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; "><code style="font-family: monospace; font-size: small !important; ">/boot/grub</code>&nbsp;目录中包含了&nbsp;<code style="font-family: monospace; font-size: small !important; ">stage1</code>、<code style="font-family: monospace; font-size: small !important; ">stage1.5</code>&nbsp;和&nbsp;<code style="font-family: monospace; font-size: small !important; ">stage2</code>&nbsp;引导加载程序，以及很多其他加载程序（例如，CR-ROM 使用的是&nbsp;<code style="font-family: monospace; font-size: small !important; ">iso9660_stage_1_5</code>）。</p></div></div><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; ">在 x86 PC 环境中，第一阶段和第二阶段的引导加载程序一起称为 Linux Loader（LILO）或 GRand Unified Bootloader（GRUB）。由于 LILO 有一些缺点，而 GRUB 克服了这些缺点，因此下面让我们就来看一下 GRUB。（有关 GRUB、LILO 和相关主题的更多内容，请参阅本文后面的&nbsp;<a href="http://www.ibm.com/developerworks/cn/linux/l-linuxboot/#resources" style="color: rgb(76, 110, 148); ">参考资料</a>&nbsp;部分的内容。）</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; ">关于 GRUB，很好的一件事情是它包含了有关 Linux 文件系统的知识。GRUB 不像 LILO 一样使用裸扇区，而是可以从 ext2 或 ext3 文件系统中加载 Linux 内核。它是通过将两阶段的引导加载程序转换成三阶段的引导加载程序来实现这项功能的。阶段 1 （MBR）引导了一个阶段 1.5 的引导加载程序，它可以理解包含 Linux 内核映像的特殊文件系统。这方面的例子包括&nbsp;<code style="font-family: monospace; font-size: small !important; ">reiserfs_stage1_5</code>（要从 Reiser 日志文件系统上进行加载）或&nbsp;<code style="font-family: monospace; font-size: small !important; ">e2fs_stage1_5</code>（要从 ext2 或 ext3 文件系统上进行加载）。当阶段 1.5 的引导加载程序被加载并运行时，阶段 2 的引导加载程序就可以进行加载了。</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; ">当阶段 2 加载之后，GRUB 就可以在请求时显示可用内核列表（在&nbsp;<code style="font-family: monospace; font-size: small !important; ">/etc/grub.conf</code>&nbsp;中进行定义，同时还有几个软符号链接<code style="font-family: monospace; font-size: small !important; ">/etc/grub/menu.lst</code>&nbsp;和&nbsp;<code style="font-family: monospace; font-size: small !important; ">/etc/grub.conf</code>）。我们可以选择内核甚至修改附加内核参数。另外，我们也可以使用一个命令行的 shell 对引导过程进行高级手工控制。</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; ">将第二阶段的引导加载程序加载到内存中之后，就可以对文件系统进行查询了，并将默认的内核映像和&nbsp;<code style="font-family: monospace; font-size: small !important; ">initrd</code>&nbsp;映像加载到内存中。当这些映像文件准备好之后，阶段 2 的引导加载程序就可以调用内核映像了。</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; "><span style="font-family: Simsun; font-size: medium; "></span></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; "><a name="N1012F"><span class="atitle" style="font-size: 1.5em; font-weight: bold; ">内核</span></a></p><div class="ibm-container ibm-alt-header dw-container-sidebar" style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.2em; margin-left: 10px; width: 320px; float: right; "><h2 style="font-family: arial, nsimsun, sans-serif; background-image: none; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 248, 252); border-top-color: rgb(204, 204, 204); border-right-color: rgb(204, 204, 204); border-bottom-color: rgb(204, 204, 204); border-left-color: rgb(204, 204, 204); border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 3px; padding-right: 5px; padding-bottom: 3px; padding-left: 5px; height: 15px; font-size: 0.75em; background-position: 0px -545px; background-repeat: repeat no-repeat; ">GRUB 中的手工引导</h2><div class="ibm-container-body" style="background-image: url(http://www.ibm.com/i/v16/t/container-gradient.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(255, 255, 255); border-left-color: rgb(204, 204, 204); font-size: 0.76em; font-family: arial, sans-serif; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; background-position: 0px 100%; background-repeat: repeat no-repeat; "><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; ">在 GRUB 命令行中，我们可以使用&nbsp;<code style="font-family: monospace; font-size: small !important; ">initrd</code>&nbsp;映像引导一个特定的内核，方法如下：</p><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; ">grub&gt; kernel /bzImage-2.6.14.2<br>[Linux-bzImage, setup=0x1400, size=0x29672e]<br>grub&gt; initrd /initrd-2.6.14.2.img<br>[Linux-initrd @ 0x5f13000, 0xcc199 bytes]<br>grub&gt; boot<br>Uncompressing Linux... Ok, booting the kernel.</p><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; ">如果您不知道要引导的内核的名称，只需使用斜线（/）然后按下 Tab 键即可。GRUB 会显示内核和&nbsp;<code style="font-family: monospace; font-size: small !important; ">initrd</code>&nbsp;映像列表。</p></div></div><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; ">当内核映像被加载到内存中，并且阶段 2 的引导加载程序释放控制权之后，内核阶段就开始了。内核映像并不是一个可执行的内核，而是一个压缩过的内核映像。通常它是一个 zImage（压缩映像，小于 512KB）或一个 bzImage（较大的压缩映像，大于 512KB），它是提前使用 zlib 进行压缩过的。在这个内核映像前面是一个例程，它实现少量硬件设置，并对内核映像中包含的内核进行解压，然后将其放入高端内存中，如果有初始 RAM 磁盘映像，就会将它移动到内存中，并标明以后使用。然后该例程会调用内核，并开始启动内核引导的过程。</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; ">当 bzImage（用于 i386 映像）被调用时，我们从<code style="font-family: monospace; font-size: small !important; ">./arch/i386/boot/head.S</code>&nbsp;的&nbsp;<code style="font-family: monospace; font-size: small !important; ">start</code>&nbsp;汇编例程开始执行（主要流程图请参看图 3）。这个例程会执行一些基本的硬件设置，并调用<code style="font-family: monospace; font-size: small !important; ">./arch/i386/boot/compressed/head.S</code>&nbsp;中的&nbsp;<code style="font-family: monospace; font-size: small !important; ">startup_32</code>&nbsp;例程。此例程会设置一个基本的环境（堆栈等），并清除 Block Started by Symbol（BSS）。然后调用一个叫做&nbsp;<code style="font-family: monospace; font-size: small !important; ">decompress_kernel</code>&nbsp;的 C 函数（在<code style="font-family: monospace; font-size: small !important; ">./arch/i386/boot/compressed/misc.c</code>&nbsp;中）来解压内核。当内核被解压到内存中之后，就可以调用它了。这是另外一个&nbsp;<code style="font-family: monospace; font-size: small !important; ">startup_32</code>&nbsp;函数，但是这个函数在&nbsp;<code style="font-family: monospace; font-size: small !important; ">./arch/i386/kernel/head.S</code>&nbsp;中。</p><p style="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; "><p style="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  face="arial, nsimsun, sans-serif"><span  style="font-size: 12px;">&nbsp;vi arch/x86/{boot/{header.S,compressed/{head_{32,64}.S,misc.c},kernel/head.S}} init/main.c</span></font></p></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; ">在这个新的&nbsp;<code style="font-family: monospace; font-size: small !important; ">startup_32</code>&nbsp;函数（也称为清除程序或进程 0）中，会对页表进行初始化，并启用内存分页功能。然后会为任何可选的浮点单元（FPU）检测 CPU 的类型，并将其存储起来供以后使用。然后调用&nbsp;<code style="font-family: monospace; font-size: small !important; ">start_kernel</code>&nbsp;函数（在&nbsp;<code style="font-family: monospace; font-size: small !important; ">init/main.c</code>&nbsp;中），它会将您带入与体系结构无关的 Linux 内核部分。实际上，这就是 Linux 内核的&nbsp;<code style="font-family: monospace; font-size: small !important; ">main</code>&nbsp;函数。</p><br><a name="fig3"><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. Linux 内核 i386 引导的主要函数流程&nbsp;</strong></a><br><img alt="Linux 内核 i386 引导的主要函数流程 " height="288" src="http://www.ibm.com/developerworks/cn/linux/l-linuxboot/fig3.gif" width="443" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; ">&nbsp;<br><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; ">通过调用&nbsp;<code style="font-family: monospace; font-size: small !important; ">start_kernel</code>，会调用一系列初始化函数来设置中断，执行进一步的内存配置，并加载初始 RAM 磁盘。最后，要调用<code style="font-family: monospace; font-size: small !important; ">kernel_thread</code>（在&nbsp;<code style="font-family: monospace; font-size: small !important; ">arch/i386/kernel/process.c</code>&nbsp;中）来启动&nbsp;<code style="font-family: monospace; font-size: small !important; ">init</code>&nbsp;函数，这是第一个用户空间进程（user-space process）。最后，启动空任务，现在调度器就可以接管控制权了（在调用&nbsp;<code style="font-family: monospace; font-size: small !important; ">cpu_idle</code>&nbsp;之后）。通过启用中断，抢占式的调度器就可以周期性地接管控制权，从而提供多任务处理能力。</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; ">在内核引导过程中，初始 RAM 磁盘（<code style="font-family: monospace; font-size: small !important; ">initrd</code>）是由阶段 2 引导加载程序加载到内存中的，它会被复制到 RAM 中并挂载到系统上。这个&nbsp;<code style="font-family: monospace; font-size: small !important; ">initrd</code>&nbsp;会作为 RAM 中的临时根文件系统使用，并允许内核在没有挂载任何物理磁盘的情况下完整地实现引导。由于与外围设备进行交互所需要的模块可能是&nbsp;<code style="font-family: monospace; font-size: small !important; ">initrd</code>&nbsp;的一部分，因此内核可以非常小，但是仍然需要支持大量可能的硬件配置。在内核引导之后，就可以正式装备根文件系统了（通过&nbsp;<code style="font-family: monospace; font-size: small !important; ">pivot_root</code>）：此时会将&nbsp;<code style="font-family: monospace; font-size: small !important; ">initrd</code>&nbsp;根文件系统卸载掉，并挂载真正的根文件系统。</p><div class="ibm-container ibm-alt-header dw-container-sidebar" style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.2em; margin-left: 10px; width: 320px; float: right; "><h2 style="font-family: arial, nsimsun, sans-serif; background-image: none; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(247, 248, 252); border-top-color: rgb(204, 204, 204); border-right-color: rgb(204, 204, 204); border-bottom-color: rgb(204, 204, 204); border-left-color: rgb(204, 204, 204); border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 3px; padding-right: 5px; padding-bottom: 3px; padding-left: 5px; height: 15px; font-size: 0.75em; background-position: 0px -545px; background-repeat: repeat no-repeat; ">decompress_kernel 输出</h2><div class="ibm-container-body" style="background-image: url(http://www.ibm.com/i/v16/t/container-gradient.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(255, 255, 255); border-left-color: rgb(204, 204, 204); font-size: 0.76em; font-family: arial, sans-serif; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; background-position: 0px 100%; background-repeat: repeat no-repeat; "><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; ">函数&nbsp;<code style="font-family: monospace; font-size: small !important; ">decompress_kernel</code>&nbsp;就是显示我们通常看到的解压消息的地方：</p><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; ">Uncompressing Linux... Ok, booting the kernel.</p></div></div><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; "><code style="font-family: monospace; font-size: small !important; ">initrd</code>&nbsp;函数让我们可以创建一个小型的 Linux 内核，其中包括作为可加载模块编译的驱动程序。这些可加载的模块为内核提供了访问磁盘和磁盘上的文件系统的方法，并为其他硬件提供了驱动程序。由于根文件系统是磁盘上的一个<em>文件系统</em>，因此&nbsp;<code style="font-family: monospace; font-size: small !important; ">initrd</code>&nbsp;函数会提供一种启动方法来获得对磁盘的访问，并挂载真正的根文件系统。在一个没有硬盘的嵌入式环境中，<code style="font-family: monospace; font-size: small !important; ">initrd</code>&nbsp;可以是最终的根文件系统，或者也可以通过网络文件系统（NFS）来挂载最终的根文件系统。</p><p>&#160;</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; "><span style="font-family: Simsun; font-size: medium; "></span></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; "><a name="N101F4"><span class="atitle" style="font-size: 1.5em; font-weight: bold; ">Init</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; ">当内核被引导并进行初始化之后，内核就可以启动自己的第一个用户空间应用程序了。这是第一个调用的使用标准 C 库编译的程序。在此之前，还没有执行任何标准的 C 应用程序。</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; ">在桌面 Linux 系统上，第一个启动的程序通常是&nbsp;<code style="font-family: monospace; font-size: small !important; ">/sbin/init</code>。但是这不是一定的。很少有嵌入式系统会需要使用&nbsp;<code style="font-family: monospace; font-size: small !important; ">init</code>&nbsp;所提供的丰富初始化功能（这是通过&nbsp;<code style="font-family: monospace; font-size: small !important; ">/etc/inittab</code>&nbsp;进行配置的）。在很多情况下，我们可以调用一个简单的 shell 脚本来启动必需的嵌入式应用程序。</p><p>&#160;</p><p style="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; "></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; "><a name="N1020D"><span class="atitle" 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; ">与 Linux 本身非常类似，Linux 的引导过程也非常灵活，可以支持众多的处理器和硬件平台。最初，加载引导加载程序提供了一种简单的方法，不用任何花架子就可以引导 Linux。LILO 引导加载程序对引导能力进行了扩充，但是它却缺少文件系统的感知能力。最新一代的引导加载程序，例如 GRUB，允许 Linux 从一些文件系统（从 Minix 到 Reise）上进行引导。</p><br><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; "><a name="resources"><span class="atitle" 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; "><strong style="font-size: 1em; font-weight: bold; ">学习</strong></p><ul style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 5px; font-size: 0.76em; font-family: Simsun; "><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; ">您可以参阅本文在 developerWorks 全球站点上的&nbsp;<a href="http://www.ibm.com/developerworks/linux/library/l-linuxboot/?S_TACT=105AGX52&amp;S_CMP=cn-a-l" target="_blank" style="color: rgb(76, 110, 148); ">英文原文</a>&nbsp;。<br><br></li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; "><a href="http://mirror.href.com/thestarman/asm/mbr/MBR_in_detail.htm" style="color: rgb(76, 110, 148); ">Boot Records Revealed</a>&nbsp;是有关 MBR 和各种引导加载程序很好的资源。这个资源不仅仅是有关 MBR 的资料的汇编，还讨论了 GRUB、LILO 和各种 Windows&#174; 引导加载程序的问题。&nbsp;<br><br></li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; ">请查看&nbsp;<a href="http://www.rwc.uc.edu/koehler/comath/42.html" style="color: rgb(76, 110, 148); ">Disk Geometry</a>&nbsp;页面来理解磁盘及其结构。您会发现有关磁盘的有用属性。&nbsp;<br><br></li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; "><a href="http://en.wikipedia.org/wiki/LiveCD" style="color: rgb(76, 110, 148); ">live CD</a>&nbsp;是一个可以从 CD 或 DVD 上引导的操作系统，它不需要使用硬盘。&nbsp;<br><br></li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; ">&#8220;<a href="http://www.ibm.com/developerworks/cn/linux/l-bootload.html" style="color: rgb(76, 110, 148); ">引导加载程序之争：了解 LILO 和 GRUB</a>&#8221;（developerWorks，2005 年 8 月）详细介绍了 LILO 和 GRUB 引导加载程序。&nbsp;<br><br></li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; ">在 developerWorks 上的&nbsp;<a href="http://www.ibm.com/developerworks/cn/linux/lpi/101.html" style="color: rgb(76, 110, 148); ">LPI 考试准备</a>&nbsp;系列教程中，我们可以学习有关引导 Linux 系统的详细介绍，以及在准备参加系统管理员认证考试时需要准备的 Linux 基础知识。&nbsp;<br><br></li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; "><a href="http://www.freshmeat.net/projects/lilo/" style="color: rgb(76, 110, 148); ">LILO</a>&nbsp;是 GRUB 的先驱，但是我们可能发现它依然可以引导 Linux。&nbsp;<br><br></li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; "><a href="http://www.netadmintools.com/html/mkinitrd.man.html" style="color: rgb(76, 110, 148); ">mkintrd</a>&nbsp;命令用来创建初始的 RAM 磁盘映像。这个命令可以用来构建初始的根文件系统，它可以用来引导允许提前加载访问真正根文件系统所需要的块设备的配置。&nbsp;<br><br></li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; ">在&nbsp;<a href="http://debianlinux.net/linux.html" style="color: rgb(76, 110, 148); ">Debian Linux Kernel Project</a>&nbsp;中，我们可以找到更多有关 Linux 内核、引导和嵌入式开发的信息。&nbsp;<br><br></li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; ">在&nbsp;<a href="http://www.ibm.com/developerworks/cn/linux/" style="color: rgb(76, 110, 148); ">developerWorks Linux 专区</a>&nbsp;中可以找到为 Linux 开发人员准备的更多资源。&nbsp;<br><br></li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; ">随时关注&nbsp;<a href="http://www.ibm.com/developerworks/offers/techbriefings/?S_TACT=105AGX52&amp;S_CMP=cn-a-l" style="color: rgb(76, 110, 148); ">developerWorks 技术事件和网络广播</a>。&nbsp;<br><br></li></ul><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; "><strong style="font-size: 1em; font-weight: bold; ">获得产品和技术</strong></p><ul style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 5px; font-size: 0.76em; font-family: Simsun; "><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; "><a href="http://www.linuxdevices.com/articles/AT8516113114.html" style="color: rgb(76, 110, 148); ">MicroMonitor</a>&nbsp;为各种小型的目标设备提供了引导环境。我们可以使用这个监视器在嵌入式环境中引导 Linux。它已经移植到 ARM、 XScale、MIPS、PowerPC、Coldfire 和 Hitachi 的 Super-H 上了。&nbsp;<br><br></li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; "><a href="http://www.gnu.org/software/grub/" style="color: rgb(76, 110, 148); ">GNU GRUB</a>&nbsp;是一个具有众多选项和灵活性的引导 shell。&nbsp;<br><br></li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; "><a href="http://www.linuxbios.org/index.php/Main_Page" style="color: rgb(76, 110, 148); ">LinuxBIOS</a>&nbsp;是 BIOS 的一个替代品。LinuxBIOS 不但可以引导 Linux，而且它本身就是一个压缩的 Linux 内核。&nbsp;<br><br></li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; "><a href="http://www.openbios.org/" style="color: rgb(76, 110, 148); ">OpenBIOS</a>&nbsp;是另一个可移植的 BIOS 项目，可以在很多体系结构上进行操作，例如 x86、Alpha 和 AMD64。&nbsp;<br><br></li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; ">在&nbsp;<a href="http://www.kernel.org/" style="color: rgb(76, 110, 148); ">kernel.org</a>&nbsp;上可以找到最新的内核树。&nbsp;<br><br></li><li style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; ">使用&nbsp;<a href="http://www.ibm.com/developerworks/downloads/?S_TACT=105AGX52&amp;S_CMP=cn-a-l" style="color: rgb(76, 110, 148); ">IBM 试用版软件</a>&nbsp;改进您的下一个开发项目，从 developerWorks 上可以直接下载这些软件。&nbsp;</li></ul><div><font face="arial, nsimsun, sans-serif"><span style="font-size: 12px;"><br></span></font></div><p>&#160;</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; "><br></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; ">from：</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; "><a href="http://www.ibm.com/developerworks/cn/linux/l-linuxboot/">http://www.ibm.com/developerworks/cn/linux/l-linuxboot/</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; "><br></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; "><br></p><p>&#160;</p></div><img src ="http://www.cppblog.com/beautykingdom/aggbug/133023.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-11-08 19:58 <a href="http://www.cppblog.com/beautykingdom/archive/2010/11/08/133023.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>aix支持大于2G的文件</title><link>http://www.cppblog.com/beautykingdom/archive/2010/11/04/132461.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Thu, 04 Nov 2010 09:42:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/11/04/132461.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/132461.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/11/04/132461.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/132461.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/132461.html</trackback:ping><description><![CDATA[<div>加</div><div>-D_LARGE_FILES 1</div><div>参数就可以了。</div>
<img src ="http://www.cppblog.com/beautykingdom/aggbug/132461.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-11-04 17:42 <a href="http://www.cppblog.com/beautykingdom/archive/2010/11/04/132461.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>shell从1+到100</title><link>http://www.cppblog.com/beautykingdom/archive/2010/10/28/131607.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Thu, 28 Oct 2010 03:12:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/10/28/131607.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/131607.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/10/28/131607.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/131607.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/131607.html</trackback:ping><description><![CDATA[
<div>第一种方法：</div><div>&nbsp;#!/bin/bash</div><div>echo -e "\t${!#}"</div><div>for (( i = 0; i &lt; 100; i++ ))</div><div>do</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;result=$[ ${result} + ${i} ]</div><div>done</div><div>echo $result</div><div>第二种方法：</div><div><span style="border-collapse: collapse; font-family: song, Verdana; font-size: 14px; line-height: 22px; ">seq -s"+" 1 100|bc</span></div><div>第三种方法：</div><div><span style="border-collapse: collapse; font-family: Monaco, Consolas, '&quot;Lucida Console&quot;', '&quot;Courier New&quot;', serif; font-size: 12px; line-height: 21px; ">s=0</span></div><div><span style="border-collapse: collapse; font-family: Monaco, Consolas, '&quot;Lucida Console&quot;', '&quot;Courier New&quot;', serif; font-size: 12px; line-height: 21px; "></span><span style="border-collapse: collapse; font-family: Monaco, Consolas, '&quot;Lucida Console&quot;', '&quot;Courier New&quot;', serif; font-size: 12px; line-height: 21px; ">for ((i=1;i&lt;=100;i++)) ; do</span></div><div><span style="border-collapse: collapse; font-family: Monaco, Consolas, '&quot;Lucida Console&quot;', '&quot;Courier New&quot;', serif; font-size: 12px; line-height: 21px; "></span><span style="border-collapse: collapse; font-family: Monaco, Consolas, '&quot;Lucida Console&quot;', '&quot;Courier New&quot;', serif; font-size: 12px; line-height: 21px; ">&nbsp;&nbsp; &nbsp;s=`expr $s + $i`</span></div><div><span style="border-collapse: collapse; font-family: Monaco, Consolas, '&quot;Lucida Console&quot;', '&quot;Courier New&quot;', serif; font-size: 12px; line-height: 21px; "></span><span style="border-collapse: collapse; font-family: Monaco, Consolas, '&quot;Lucida Console&quot;', '&quot;Courier New&quot;', serif; font-size: 12px; line-height: 21px; ">done</span></div><div><span style="border-collapse: collapse; font-family: Monaco, Consolas, '&quot;Lucida Console&quot;', '&quot;Courier New&quot;', serif; font-size: 12px; line-height: 21px; "></span><span style="border-collapse: collapse; font-family: Monaco, Consolas, '&quot;Lucida Console&quot;', '&quot;Courier New&quot;', serif; font-size: 12px; line-height: 21px; ">echo $s</span></div><div>第四种方法：</div><div><table cellspacing="0" cellpadding="0" style="word-wrap: break-word; empty-cells: show; border-collapse: collapse; line-height: normal; table-layout: fixed; margin-left: 1px; font-family: song, Verdana; font-size: 12px; width: 910px; "><tbody style="word-wrap: break-word; line-height: normal; "><tr style="word-wrap: break-word; line-height: normal; "><td class="t_msgfont" id="postmessage_12782032" style="word-wrap: break-word; color: rgb(0, 0, 0); font: normal normal normal 12px/normal song, Verdana; line-height: 1.6em; font-size: 14px; ">#!/bin/sh<br style="word-wrap: break-word; line-height: normal; ">s=0<br style="word-wrap: break-word; line-height: normal; ">for i in `seq 1 100`<br style="word-wrap: break-word; line-height: normal; ">do<br style="word-wrap: break-word; line-height: normal; ">s=`expr $s + $i`<br style="word-wrap: break-word; line-height: normal; ">done<br style="word-wrap: break-word; line-height: normal; ">echo $s<br><br>第五种方法：<br><span  style="line-height: normal; font-size: 12px; "><table cellspacing="0" cellpadding="0" style="word-wrap: break-word; empty-cells: show; border-collapse: collapse; line-height: normal; table-layout: fixed; margin-left: 1px; width: 898px; "><tbody style="word-wrap: break-word; line-height: normal; "><tr style="word-wrap: break-word; line-height: normal; "><td class="t_msgfont" id="postmessage_12783476" style="word-wrap: break-word; color: rgb(0, 0, 0); font: normal normal normal 12px/normal song, Verdana; line-height: 1.6em; font-size: 14px; ">echo {1..100}|sed 's/ /+/g'|bc<br><br><br></td></tr></tbody></table></span>from：<br><a href="http://bbs.chinaunix.net/thread-1777298-1-1.html">http://bbs.chinaunix.net/thread-1777298-1-1.html</a></td></tr></tbody></table></div>
<img src ="http://www.cppblog.com/beautykingdom/aggbug/131607.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-10-28 11:12 <a href="http://www.cppblog.com/beautykingdom/archive/2010/10/28/131607.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>收集的一些还不错的网站</title><link>http://www.cppblog.com/beautykingdom/archive/2010/10/07/128909.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Thu, 07 Oct 2010 05:32:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/10/07/128909.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/128909.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/10/07/128909.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/128909.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/128909.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/beautykingdom/archive/2010/10/07/128909.html'>阅读全文</a><img src ="http://www.cppblog.com/beautykingdom/aggbug/128909.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-10-07 13:32 <a href="http://www.cppblog.com/beautykingdom/archive/2010/10/07/128909.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AIX系统信息查看</title><link>http://www.cppblog.com/beautykingdom/archive/2010/10/02/128281.html</link><dc:creator>chatler</dc:creator><author>chatler</author><pubDate>Sat, 02 Oct 2010 01:19:00 GMT</pubDate><guid>http://www.cppblog.com/beautykingdom/archive/2010/10/02/128281.html</guid><wfw:comment>http://www.cppblog.com/beautykingdom/comments/128281.html</wfw:comment><comments>http://www.cppblog.com/beautykingdom/archive/2010/10/02/128281.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/beautykingdom/comments/commentRss/128281.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/beautykingdom/services/trackbacks/128281.html</trackback:ping><description><![CDATA[
<span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><div><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">看编译器版本：</span>lslpp -l | grep Xlc</div><div>bootinfo -k(小写)</div></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">返回当前的启动模式/返回机器的钥匙的位置</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">1 Key is in Secure position.</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">2 Key is in Service position.</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">3 Key is in Normal position.</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">bootinfo -K(大写)</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">返回当前</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><span href="tag.php?name=%E7%B3%BB%E7%BB%9F" class="t_tag" style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; cursor: pointer; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(255, 0, 0); white-space: nowrap; ">系统</span></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">运行的内核为32位还是64位</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">bootinfo -m</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">返回机器类型码</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">bootinfo -c</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">-c Displays bootp daemon reply packet information stored with IPL control block.</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">bootinfo -t</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">返回当前启动类型</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">1 Disk boot</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">3 CD-ROM boot</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">4 Tape boot</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">5 Network boot</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">bootinfo -z</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">返回机器是否支持多</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><span href="tag.php?name=%E5%A4%84%E7%90%86%E5%99%A8" class="t_tag" style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; cursor: pointer; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(255, 0, 0); white-space: nowrap; ">处理器</span></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">0 不支持</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">1 支持</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">bootinfo -T</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">返回机器的硬件平台类型，比如rspc</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">bootinfo -r</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">返回实际</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><span href="tag.php?name=%E5%86%85%E5%AD%98" class="t_tag" style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; cursor: pointer; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(255, 0, 0); white-space: nowrap; ">内存</span></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">容量，单位为kbytes</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">bootinfo -b</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">返回最后一次启动的设备</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">bootinfo -y</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">返回机器硬件是32位还是64位</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">uname -p</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">返回系统芯片类型，如powerpc</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">uname -M</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; "></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">返回机器型号，如</span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><span href="tag.php?name=IBM" class="t_tag" style="word-wrap: break-word; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; text-decoration: none; line-height: normal; cursor: pointer; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(255, 0, 0); white-space: nowrap; ">IBM</span></span><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; ">,7026-B80</span>

<div><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><br></span></div><div><span style="border-collapse: collapse; color: rgb(68, 68, 68); font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; "><span  style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; line-height: normal; font-size: 13px; ">内存lsattr -El mem0<br>cpu lsdev -C |grep proc<br>CPU的信息lsattr -El proc0</span></span></div><img src ="http://www.cppblog.com/beautykingdom/aggbug/128281.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/beautykingdom/" target="_blank">chatler</a> 2010-10-02 09:19 <a href="http://www.cppblog.com/beautykingdom/archive/2010/10/02/128281.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>