﻿<?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++博客-天之道-随笔分类-Linux</title><link>http://www.cppblog.com/zhenglinbo/category/19472.html</link><description>享受编程的乐趣。</description><language>zh-cn</language><lastBuildDate>Wed, 15 May 2013 04:32:22 GMT</lastBuildDate><pubDate>Wed, 15 May 2013 04:32:22 GMT</pubDate><ttl>60</ttl><item><title>exec函数</title><link>http://www.cppblog.com/zhenglinbo/archive/2013/05/14/200259.html</link><dc:creator>hoshelly</dc:creator><author>hoshelly</author><pubDate>Tue, 14 May 2013 09:37:00 GMT</pubDate><guid>http://www.cppblog.com/zhenglinbo/archive/2013/05/14/200259.html</guid><wfw:comment>http://www.cppblog.com/zhenglinbo/comments/200259.html</wfw:comment><comments>http://www.cppblog.com/zhenglinbo/archive/2013/05/14/200259.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zhenglinbo/comments/commentRss/200259.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zhenglinbo/services/trackbacks/200259.html</trackback:ping><description><![CDATA[<div><span style="font-size: 10pt;">用f o r k函数创建子进程后，子进程往往要调用一种e x e c函数以执行另一个程序。</span><span style="font-size: 10pt;">当进程调用一种e x e c函数时，该进程完全由新程序代换，而新程序则从其 m a i n函数开始执行。</span><span style="font-size: 10pt;">因为调用e x e c并不创建新进程，所以前后的进程I D并未改变。</span><span style="font-size: 10pt; color: red;"><u>e x e c只是用另一个新程序替换了</u></span><span style="font-size: 10pt; color: red;"><u>当前进程的正文、数据、堆和栈段。</u></span></div><div><span style="font-size: 10pt;">有六种不同的e x e c函数可供使用（具体参考APUE），它们常常被统称为e x e c函数。这些e x e c函数都是U N I X进</span><span style="font-size: 10pt;">程控制原语。用f o r k可以创建新进程，用e x e c可以执行新的程序。e x i t函数和两个w a i t函数处理</span><span style="font-size: 10pt;">终止和等待终止。这些是我们需要的基本的进程控制原语。<br /><br /></span></div><img src ="http://www.cppblog.com/zhenglinbo/aggbug/200259.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zhenglinbo/" target="_blank">hoshelly</a> 2013-05-14 17:37 <a href="http://www.cppblog.com/zhenglinbo/archive/2013/05/14/200259.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>init进程 与僵尸进程</title><link>http://www.cppblog.com/zhenglinbo/archive/2013/05/14/200258.html</link><dc:creator>hoshelly</dc:creator><author>hoshelly</author><pubDate>Tue, 14 May 2013 09:32:00 GMT</pubDate><guid>http://www.cppblog.com/zhenglinbo/archive/2013/05/14/200258.html</guid><wfw:comment>http://www.cppblog.com/zhenglinbo/comments/200258.html</wfw:comment><comments>http://www.cppblog.com/zhenglinbo/archive/2013/05/14/200258.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zhenglinbo/comments/commentRss/200258.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zhenglinbo/services/trackbacks/200258.html</trackback:ping><description><![CDATA[<div></div><div><span style="font-size: 10pt;">在说明f o r k函数时，一定是一个父进程生成一个子进程。上面又说明了子进程将其终止状</span><span style="font-size: 10pt;">态返回给父进程。但是如果父进程在子进程之前终止，则将如何呢？其回答是对于其父进程已</span><span style="font-size: 10pt;">经终止的所有进程，它们的父进程都改变为i n i t进程。</span></div><div><span style="font-size: 10pt;">我们称这些进程由i n i t进程领养。其操作</span><span style="font-size: 10pt;">过程大致是：在一个进程终止时，内核逐个检查所有活动进程，以判断它是否是正要终止的进</span><span style="font-size: 10pt;">程的子进程，如果是，则该进程的父进程I D就更改为1 ( i n i t进程的I D )。这种处理方法保证了每</span><span style="font-size: 10pt;">个进程有一个父进程。<br /><br /></span><div><span style="font-size: 10pt;">如果子进程在父进程之前终止，那么父进程又如何能在做相应检</span><span style="font-size: 10pt;">查时得到子进程的终止状态呢？对此问题的回答是内核为每个终止子进程保存了一定量的信</span></div><div><span style="font-size: 10pt;">息，所以当终止进程的父进程调用 w a i t或waitpid 时，可以得到有关信息。这种信息至少包括</span><span style="font-size: 10pt;">进程I D、该进程的终止状态、以反该进程使用的 C P U时间总量。内核可以释放终止进程所使</span><span style="font-size: 10pt;">用的所有存储器，关闭其所有打开文件。在 U N I X术语中，一个已经终止、但是其父进程尚未</span><span style="font-size: 10pt;">对其进行善后处理（获取终止子进程的有关信息、释放它仍占用的资源）的进程被称为僵死进程（z o m b i e）。p s ( 1 )命令将僵死进程的状态打印为 Z。<br /><br /></span><div><span style="font-size: 10pt;">一个由i n i t进程领养的进程终止时会发生什么?它会不会变成一</span><span style="font-size: 10pt;">个僵死进程？对此问题的回答是&#8220;否&#8221;，因为i n i t被编写成只要有一个子进程终止， i n i t就会调</span><span style="font-size: 10pt;">用一个w a i t函数取得其终止状态。这样也就防止了在系统中有很多僵死进程。当提及&#8220;一个i n i t</span><span style="font-size: 10pt;">的子进程&#8221;时，这指的是i n i t直接产生的进程，或者是其父</span><span style="font-size: 10pt;">进程已终止，由init 领养的进程。</span></div></div></div><img src ="http://www.cppblog.com/zhenglinbo/aggbug/200258.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zhenglinbo/" target="_blank">hoshelly</a> 2013-05-14 17:32 <a href="http://www.cppblog.com/zhenglinbo/archive/2013/05/14/200258.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>fork 和 vfork 的区别 &amp; exit 和_exit的区别</title><link>http://www.cppblog.com/zhenglinbo/archive/2013/05/14/200257.html</link><dc:creator>hoshelly</dc:creator><author>hoshelly</author><pubDate>Tue, 14 May 2013 09:26:00 GMT</pubDate><guid>http://www.cppblog.com/zhenglinbo/archive/2013/05/14/200257.html</guid><wfw:comment>http://www.cppblog.com/zhenglinbo/comments/200257.html</wfw:comment><comments>http://www.cppblog.com/zhenglinbo/archive/2013/05/14/200257.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zhenglinbo/comments/commentRss/200257.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zhenglinbo/services/trackbacks/200257.html</trackback:ping><description><![CDATA[<span style="font-size: 10pt;">1.1<br />fork可以创建一个新的子进程，调用一次，返回两次，一次返回0值给子进程，另一次返回新的子进程的ID给父进程 。子进程是父进程的复制品，拥有父进程的数据空间、堆和栈，父子进程并不共享存储空间，如果正文段是只读的，那么父子进程共享正文段。</span><br /><span style="font-size: 10pt;">一般而言，fork之后是父进程先执行还是子进程先执行是不确定的，这取决于内核的调度算法。</span><br /><span style="font-size: 10pt;">fork有两种用法：</span><br /><span style="font-size: 10pt;">（1）一个父进程希望复制自己，使父、子进程同时执行不同的代码段。</span><span style="font-size: 10pt;">这在网络服务进程</span><span style="font-size: 10pt;">中是常见的&#8212;&#8212;父进程等待委托者的服务请求。当这种请求到达时，父进程调用 f o r k，使子进</span><span style="font-size: 10pt;">程处理此请求。父进程则继续等待下一个服务请求。</span><div><span style="font-size: 10pt;">（2） 一个进程要执行一个不同的程序。这对s h e l l是常见的情况。在这种情况下，子进程在</span><span style="font-size: 10pt;">从f o r k返回后立即调用e x e c。</span></div><br /><span style="font-size: 10pt;">1.2<br />vfork用于创建一个新的进程，而新的进程的目的就是exec一个新程序，vfork并不将父进程的地址空间复制给子进程，因为子进程会立即调用exec（_exit），于是也就不会访问地址空间。不过它在调用exec或_exit之前，它在父进程的空间中运行。<br /><br />fork创建的子进程共享父进程的数据段、堆栈段；vfork创建的子进程共享父进程的数据段。<br /><br />vfork与fork的另一个区别是：vfork保证子进程先运行，在它调用exec或exit之后父进程才可能被调度运行，（如果在调用这两个函数之前子进程依赖于父进程的进一步动作，则会导致死锁）。<br /><br />2.1<br />exit和_exit都是正常终止进程，_exit用于vfork时父进程有可能会被调度，它们都不同于异常终止abort，在异常终止情况下，内核（不是进程）产生一个指示其终止异常终止原因的终止状态。</span><img src ="http://www.cppblog.com/zhenglinbo/aggbug/200257.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zhenglinbo/" target="_blank">hoshelly</a> 2013-05-14 17:26 <a href="http://www.cppblog.com/zhenglinbo/archive/2013/05/14/200257.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ourhdr.h编译错误时解决办法</title><link>http://www.cppblog.com/zhenglinbo/archive/2013/05/14/200253.html</link><dc:creator>hoshelly</dc:creator><author>hoshelly</author><pubDate>Tue, 14 May 2013 08:03:00 GMT</pubDate><guid>http://www.cppblog.com/zhenglinbo/archive/2013/05/14/200253.html</guid><wfw:comment>http://www.cppblog.com/zhenglinbo/comments/200253.html</wfw:comment><comments>http://www.cppblog.com/zhenglinbo/archive/2013/05/14/200253.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zhenglinbo/comments/commentRss/200253.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zhenglinbo/services/trackbacks/200253.html</trackback:ping><description><![CDATA[网上找的，摘抄如下：<br /><br /><div><span style="font-size: 12px;">＃include "apue.h"</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; 这个头文件是作者把每个例程中常用的标准头文件，一些常用的出错处理函数（err_**（）之类的函</span></div><div><span style="font-size: 12px;">数）和一些常用的宏定义给整理在一个头文件中。这个可以省去在每个例程中录入较多的重复代码，这样可</span></div><div><span style="font-size: 12px;">以减少每个例程的长度。但给读者带来了不少麻烦。下面给出源代码的编译方法。</span></div><div><span style="font-size: 12px;"><br /></span></div><div>&nbsp;</div><div><span style="font-size: 12px;"><br /></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;">1.APUE2源代码下载：http://www.apuebook.com/src.tar.gz</span></div><div><span style="font-size: 12px;">2.我保存到了/home/wx下.解压缩:tar zxvf src.tar.gz</span></div><div><span style="font-size: 12px;">3.cd apue.2e到apue.2e目录（查看README,告诉我们linux系统只要修改Make.defines.linux再make）</span></div><div><span style="font-size: 12px;">4.vi Make.defines.linux 修改WKDIR=/home/wx/apue.2e 就是说工作目录为WKDIR=/home/wx/apue.2e</span></div><div><span style="font-size: 12px;">5.修改/home/wx/apue.2e/std/linux.mk把全部的nawk改为awk.因些linux默认没有nawk</span></div><div><span style="font-size: 12px;">6.cd /home/wx/apue.2e</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">&nbsp; &nbsp;make</span></div><div><span style="font-size: 12px;">7.把生成的apue.2e/lib/libapue.a与apue.2e/include/apue.h拷贝到你编写的源代码目录下。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">&nbsp; &nbsp;（注：你可以把libapue.a和apue.h保存在容易找到的文件夹中，以便使用）</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">8.使用gcc -o ls1 ls1.c &nbsp;libapue.a来编译你的源代码</span></div><div><span style="font-size: 12px;">9.成功<br /><br /><br /></span></div><div style="font-family: Tahoma; font-size: 11px;"></div><img src ="http://www.cppblog.com/zhenglinbo/aggbug/200253.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zhenglinbo/" target="_blank">hoshelly</a> 2013-05-14 16:03 <a href="http://www.cppblog.com/zhenglinbo/archive/2013/05/14/200253.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vim文本的选择</title><link>http://www.cppblog.com/zhenglinbo/archive/2013/04/13/199417.html</link><dc:creator>hoshelly</dc:creator><author>hoshelly</author><pubDate>Sat, 13 Apr 2013 14:57:00 GMT</pubDate><guid>http://www.cppblog.com/zhenglinbo/archive/2013/04/13/199417.html</guid><wfw:comment>http://www.cppblog.com/zhenglinbo/comments/199417.html</wfw:comment><comments>http://www.cppblog.com/zhenglinbo/archive/2013/04/13/199417.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zhenglinbo/comments/commentRss/199417.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zhenglinbo/services/trackbacks/199417.html</trackback:ping><description><![CDATA[<div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">在正常模式下（按ESC进入）按键v进入可视化模式，然后按键盘左右键或h,l键即可实现文本的选择。</span></div><div><span style="font-size: 12px;">其它相关命令：</span></div><div><span style="font-size: 12px;">v：按字符选择。经常使用的模式，所以亲自尝试一下它。</span></div><div><span style="font-size: 12px;">V：按行选择。这在你想拷贝或者移动很多行的文本的时候特别有用。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">CTRL＋v：按块选择。非常强大，只在很少的编辑器中才有这样的功能。你可以选择一个矩形块，并且在这个矩形里面的文本会被高亮。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">值得注意的是如果VIM中使用自动换行，那么直到你按ENTER换行前，VIM都会将你之前输入的内容视为一行而不是你看到的好几行，按块选择时就会按VIM中的行来选择块。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">在选择模式的时候使用上面所述的方向键和命令（motion）。比如，vwww，会高亮光标前面的三个词。Vjj 将会高亮当前行以及下面两行。</span></div><img src ="http://www.cppblog.com/zhenglinbo/aggbug/199417.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zhenglinbo/" target="_blank">hoshelly</a> 2013-04-13 22:57 <a href="http://www.cppblog.com/zhenglinbo/archive/2013/04/13/199417.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>wait 和waitpid详解</title><link>http://www.cppblog.com/zhenglinbo/archive/2013/04/13/199412.html</link><dc:creator>hoshelly</dc:creator><author>hoshelly</author><pubDate>Sat, 13 Apr 2013 14:05:00 GMT</pubDate><guid>http://www.cppblog.com/zhenglinbo/archive/2013/04/13/199412.html</guid><wfw:comment>http://www.cppblog.com/zhenglinbo/comments/199412.html</wfw:comment><comments>http://www.cppblog.com/zhenglinbo/archive/2013/04/13/199412.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zhenglinbo/comments/commentRss/199412.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zhenglinbo/services/trackbacks/199412.html</trackback:ping><description><![CDATA[<div><span style="font-size: 12px;">wait的函数原型是： 　</span></div><div><span style="font-size: 12px;">#include&lt;sys/types.h&gt;</span></div><div><span style="font-size: 12px;">#include &lt;sys/wait.h&gt;</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">pid_t wait(int *status) 　　　　</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp; 进程一旦调用了wait，就立即阻塞自己，由wait自动分析是</span></div><div><span style="font-size: 12px;">否当前进程的某个子进程已经退出，如果让它找到了这样一个</span></div><div><span style="font-size: 12px;">已经变成僵尸的子进程， wait就会收集这个子进程的信息，并</span></div><div><span style="font-size: 12px;">把它彻底销毁后返回；如果没有找到这样一个子进程，wait就</span></div><div><span style="font-size: 12px;">会一直阻塞在这里，直到有一个出现为止。　　　　</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp; 参数status用来保存被收集进程退出时的一些状态，它是</span></div><div><span style="font-size: 12px;">一个指向int类型的指针。但如果我们对这个子进程是如何死掉</span></div><div><span style="font-size: 12px;">的毫不在意，只想把这个僵尸进程消灭掉，（事实上绝大多数</span></div><div><span style="font-size: 12px;">情况下，我们都会这样想），我们就可以设定这个参数为</span></div><div><span style="font-size: 12px;">NULL，就象下面这样：　　 　　pid = wait(NULL);</span></div><div><span style="font-size: 12px;">如果成功，wait会返回被收集的子进程的进程ID，如果调用进</span></div><div><span style="font-size: 12px;">程没有子进程，调用就会失败，此时wait返回-1，同时errno被</span></div><div><span style="font-size: 12px;">置为ECHILD。　</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp; waitpid的函数原型是： 　　</span></div><div><span style="font-size: 12px;">waitpid系统调用在Linux函数库中的原型是： 　　</span></div><div><span style="font-size: 12px;">#include &lt;sys/types.h&gt;#include &lt;sys/wait.h&gt;</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">pid_t waitpid(pid_t pid,int *status,int options)</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp; 从本质上讲，系统调用waitpid和wait的作用是完全相同</span></div><div><span style="font-size: 12px;">的，但waitpid多出了两个可由用户控制的参数pid和options，</span></div><div><span style="font-size: 12px;">从而为我们编程提供了另一种更灵活的方式。</span></div><div><span style="font-size: 12px;">下面我们就来详细介绍一下这两个参数：　　 　　</span></div><div><span style="font-size: 12px;">&#9679; pid 　　　　从参数的名字pid和类型pid_t中就可以看出，</span></div><div><span style="font-size: 12px;">这里需要的是一个进程ID。但当pid取不同的值时，在这里有不</span></div><div><span style="font-size: 12px;">同的意义。 　　　　pid&gt;0时，只等待进程ID等于pid的子进</span></div><div><span style="font-size: 12px;">程，不管其它已经有多少子进程运行结束退出了，只要指定的</span></div><div><span style="font-size: 12px;">子进程还没有结束，waitpid就会一直等下去。　　 　　pid=-</span></div><div><span style="font-size: 12px;">1时，等待任何一个子进程退出，没有任何限制，此时waitpid</span></div><div><span style="font-size: 12px;">和wait的作用一模一样。 　　　　pid=0时，等待同一个进程</span></div><div><span style="font-size: 12px;">组中的任何子进程，如果子进程已经加入了别的进程组，</span></div><div><span style="font-size: 12px;">waitpid不会对它做任何理睬。 　　　　pid&lt;-1时，等待一个</span></div><div><span style="font-size: 12px;">指定进程组中的任何子进程，这个进程组的ID等于pid的绝对</span></div><div><span style="font-size: 12px;">值。 　　</span></div><div><span style="font-size: 12px;">&#9679; options 　　options提供了一些额外的选项来控制waitpid，</span></div><div><span style="font-size: 12px;">目前在Linux中只支持WNOHANG和WUNTRACED两个选项，</span></div><div><span style="font-size: 12px;">这是两个常数，可以用"|"运算符把它们连接起来使用，比如：</span></div><div><span style="font-size: 12px;">　　ret=waitpid(-1,NULL,WNOHANG | WUNTRACED); 　　</span></div><div><span style="font-size: 12px;">如果我们不想使用它们，也可以把options设为0，如： 　　</span></div><div><span style="font-size: 12px;">ret=waitpid(-1,NULL,0); 　　　　如果使用了WNOHANG参数</span></div><div><span style="font-size: 12px;">调用waitpid，即使没有子进程退出，它也会立即返回，不会像</span></div><div><span style="font-size: 12px;">wait那样永远等下去。 　　　　而WUNTRACED参数，由于</span></div><div><span style="font-size: 12px;">涉及到一些跟踪调试方面的知识，加之极少用到，这里就不多</span></div><div><span style="font-size: 12px;">费笔墨了，有兴趣的读者可以自行查阅相关材料。　　　　看</span></div><div><span style="font-size: 12px;">到这里，聪明的读者可能已经看出端倪了--wait不就是经过包装</span></div><div><span style="font-size: 12px;">的waitpid吗？没错，察看&lt;内核源码目录&gt;/include/unistd.h文</span></div><div><span style="font-size: 12px;">件349-352行就会发现以下程序段：　　 　　static inline</span></div><div><span style="font-size: 12px;">pid_t wait(int * wait_stat) 　　{ 　　 return waitpid(-</span></div><div><span style="font-size: 12px;">1,wait_stat,0); 　　} 　　 　　返回值和错误 　　　　</span></div><div><span style="font-size: 12px;">waitpid的返回值比wait稍微复杂一些，一共有3种情况： 　</span></div><div><span style="font-size: 12px;">&#9679; 当正常返回的时候，waitpid返回收集到的子进程的进程ID；</span></div><div><span style="font-size: 12px;">&#9679; 如果设置了选项WNOHANG，而调用中waitpid发现没有已</span></div><div><span style="font-size: 12px;">退出的子进程可收集，则返回0； 　　 　　</span></div><div><span style="font-size: 12px;">&#9679; 如果调用中出错，则返回-1，这时errno会被设置成相应的</span></div><div><span style="font-size: 12px;">值以指示错误所在；当pid所指示的子进程不存在，或此进程存</span></div><div><span style="font-size: 12px;">在，但不是调用进程的子进程，waitpid就会出错返回，这时</span></div><div><span style="font-size: 12px;">errno被设置为ECHILD 其它： 调用 wait＆waitpid 来处理终止</span></div><div><span style="font-size: 12px;">的子进程： pid_t wait(int * statloc); pid_t waitpid(pid_t pid,</span></div><div><span style="font-size: 12px;">int *statloc, int options); 两个函数都返回两个值：函数的返回</span></div><div><span style="font-size: 12px;">值和终止的子进程ID，而子进程终止的状态则是通过statloc指</span></div><div><span style="font-size: 12px;">针返回的。 wait＆waitpid 的区别是显而易见的，wait等待第一</span></div><div><span style="font-size: 12px;">个终止的子进程，而waitpid则可以指定等待特定的子进程。这</span></div><div><span style="font-size: 12px;">样的区别可能会在下面这种情况时表现得更加明显：当同时有</span></div><div><span style="font-size: 12px;">5个客户连上服务器，也就是说有五个子进程分别对应了5个客</span></div><div><span style="font-size: 12px;">户，此时，五个客户几乎在同时请求终止，这样一来，几乎同</span></div><div><span style="font-size: 12px;">时，五个FIN发向服务器，同样的，五个SIGCHLD信号到达服</span></div><div><span style="font-size: 12px;">务器，然而，UNIX的信号往往是不会排队的，显然这样一来，</span></div><div><span style="font-size: 12px;">信号处理函数将只会执行一次，残留剩余四个子进程作为僵尸</span></div><div><span style="font-size: 12px;">进程驻留在内核空间。此时，正确的解决办法是利用waitpid(-</span></div><div><span style="font-size: 12px;">1, &amp;stat, WNOHANG)防止留下僵尸进程。其中的pid为－1表</span></div><div><span style="font-size: 12px;">明等待第一个终止的子进程，而WNOHANG选择项通知内核在</span></div><div><span style="font-size: 12px;">没有已终止进程项时不要阻塞。</span></div><div><span style="font-size: 12px;">wait＆waitpid 区别 :</span></div><div><span style="font-size: 12px;">waitpid提供了wait函数不能实现的3个功能: waitpid等待特定的</span></div><div><span style="font-size: 12px;">子进程, 而wait则返回任一终止状态的子进程; waitpid提供了一</span></div><div><span style="font-size: 12px;">个wait的非阻塞版本; waitpid支持作业控制(以WUNTRACED选</span></div><div><span style="font-size: 12px;">项). 用于检查wait和waitpid两个函数返回终止状态的宏: 这两个</span></div><div><span style="font-size: 12px;">函数返回的子进程状态都保存在statloc指针中, 用以下3个宏可</span></div><div><span style="font-size: 12px;">以检查该状态: WIFEXITED(status): 若为正常终止, 则为真. 此</span></div><div><span style="font-size: 12px;">时可执行 WEXITSTATUS(status): 取子进程传送给exit或_exit</span></div><div><span style="font-size: 12px;">参数的低8位. WIFSIGNALED(status): 若为异常终止, 则为真.</span></div><div><span style="font-size: 12px;">此时可执行 WTERMSIG(status): 取使子进程终止的信号编号.</span></div><div><span style="font-size: 12px;">WIFSTOPPED(status): 若为当前暂停子进程, 则为真. 此时可</span></div><div><span style="font-size: 12px;">执行 WSTOPSIG(status): 取使子进程暂停的信号编号<br /></span></div><img src ="http://www.cppblog.com/zhenglinbo/aggbug/199412.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zhenglinbo/" target="_blank">hoshelly</a> 2013-04-13 22:05 <a href="http://www.cppblog.com/zhenglinbo/archive/2013/04/13/199412.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux的一些shell命令基本操作</title><link>http://www.cppblog.com/zhenglinbo/archive/2012/08/02/186017.html</link><dc:creator>hoshelly</dc:creator><author>hoshelly</author><pubDate>Thu, 02 Aug 2012 03:49:00 GMT</pubDate><guid>http://www.cppblog.com/zhenglinbo/archive/2012/08/02/186017.html</guid><wfw:comment>http://www.cppblog.com/zhenglinbo/comments/186017.html</wfw:comment><comments>http://www.cppblog.com/zhenglinbo/archive/2012/08/02/186017.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zhenglinbo/comments/commentRss/186017.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zhenglinbo/services/trackbacks/186017.html</trackback:ping><description><![CDATA[我们学习Linux的时候势必要学习一大堆对于大部分正常人来说枯燥无比的命令行，因为是第一次尝试在一个黑箱子里面敲一串一串不熟悉的命令，可以理解的啦。现在我总结出一些Linux中比较常用的命令行。<br /><br />一）列出文件：ls ，如果要列出本目录下的文件属性呢，例如想知道他们的文件权限、大小、日期，那么就用 ls -l ，也可用其命令别名 ll 。<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;我们都知道Linux中都有一些隐藏的文件，那么如何显示出它们呢？用 ls -a 即可显示出所有文件，包括隐藏文件。要列出这些文件的属性，用 ls -al&nbsp;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;列出目录用：ls -d<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;如果我们想找出一个特定的文件如file 的信息，那么可以用ls &nbsp;-l file ，又如要寻找一个前缀为test的文件的信息，可以这样：ls -l test*，*为通配符。<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;如果我们想找出文件名中带有数字或字母的相关文件，可以这样 : ls -f [0-9]* / ls -f [a-z]*<br /><br />二）打开文件或目录：如想打开名为 file.txt文件，用cat file.txt即可显示出内容。如想把文件内容的行号显示出来，用 cat -n file.txt 即可 ；打开目录tmp 则用 cd tmp<br /><br />三）复制文件： 如想把文件file.txt 复制到目录 /test 下，即可用：cp file.txt /test ；如想把目录 /etc/ 的所有内容复制到 /tmp，用：cp /etc/ /tmp<br /><br />四）删除文件或目录：如想删除文件file.txt 则可： rm file.txt 。如想把目录tmp（包括有内容的目录）都删除掉，用 rm -rf tmp ，而 rmdir tmp 删除的是一个空目录。<br /><br />五）移动文件或重命名：如把文件file.txt移动到目录tmp中： mv file.txt tmp 。把文件file.txt重命名为 test.txt，则可： mv file.txt test.txt<br /><br />六）翻页查看命令：1. 如想查看/etc/中的文件man.config，可 more /etc/man.config ，敲空格键表示向下翻一页；Enter表示向下翻&#8220;一行&#8221;；/字符串可以向下搜索字符串：如搜索word，可以 /word ；离开more 可以用 q ；2. 也可用 less 进行翻页操作：less /etc/man.config ，使用less可以向前或向后翻页，而more只能向后翻页；？字符串表示向前搜索的功能，其他操作和more 大体相同。<br /><br />七）创建新文件或目录 : 如创建新文件 test.txt 可以： touch test.txt ；创建目录abc,用命令：mkdir abc . 如果我们要创建一个名为junk.data ,大小为1M,内容为空的文件，该怎么办呢？可以使用命令： dd if=/dev/zero of=junk.data bs=1M count=1 即可，其中dd是用来创建特定大小文件的命令，dd命令会克隆给定的输入内容，然后将一模一样的一份副本写入到输出，stdin、设备文件、普通文件都可以作为输入. if 代表输入文件， of 代表输出文件， bs代表以字节为单位的块大小，count代表要被复制的块数。<br /><br />八）改变文件的权限： 1. 使用符号方法改变文件权限：在此之前了解下who /action 的知识，u表示属主、g表示组、o表示其他、a表示所有；+表示增加文件权限、-表示减少文件权限、=明确地设置文件权限。好了，如果现在我们想把一个目录下的所有文件都改变为对所有人均可访问，则可用命令：chmod a=r * （或chmod guo=r *)，注意空格。<br />如果想阻止除了文件属主之外的任何人写文件 test.txt ，可用命令： chmod go-w test.txt&nbsp;<br />2. 使用八进制方法改变文件权限：r=4,w=2,x=1. 把各个想要赋予的权限值相加即可得到用来指定文件属主、组和其他用户对文件的权限。 如：对文件test.txt 改为对所有均有读、写、执行的权限：chmod 777 test.txt<br /><br />九）改变文件属主和组： 1. 改变文件属主：如把文件test.txt 改变为 zlb 所属有，则可 chown zlb: test.txt ，冒号不能省略。 2. 改变文件所属的组：可以用1中 chown :authors test.txt 改变文件test.txt所属的组；也可以用 chgrp authors test.txt 改变文件为authors这个组所有。<br /><br /><br /><img src ="http://www.cppblog.com/zhenglinbo/aggbug/186017.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zhenglinbo/" target="_blank">hoshelly</a> 2012-08-02 11:49 <a href="http://www.cppblog.com/zhenglinbo/archive/2012/08/02/186017.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux学习方向（转）</title><link>http://www.cppblog.com/zhenglinbo/archive/2012/06/08/178103.html</link><dc:creator>hoshelly</dc:creator><author>hoshelly</author><pubDate>Fri, 08 Jun 2012 10:18:00 GMT</pubDate><guid>http://www.cppblog.com/zhenglinbo/archive/2012/06/08/178103.html</guid><wfw:comment>http://www.cppblog.com/zhenglinbo/comments/178103.html</wfw:comment><comments>http://www.cppblog.com/zhenglinbo/archive/2012/06/08/178103.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zhenglinbo/comments/commentRss/178103.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zhenglinbo/services/trackbacks/178103.html</trackback:ping><description><![CDATA[<div><span style="font-size: 12px;">掌握Linux学习方法学好Linux</span></div><div><span style="font-size: 12px;">如果你爱好学习知识，尤其是Linux操作系统知识，随着Linux应用的扩展，许多朋友开始接触Linux，可你不知道去哪里找到这些知识，来这里，让你更加了解Linux学习方法。让你全面掌握Linux学习方法。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">1．学习的目的</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">通过Linux的学习掌握UNIX的目的想必不用多说了，在这个网络人才身价倍增的年代，想靠技术吃饭又不想掌握网络和编程技术是不明智的。当人们第一次听说Linux并跃跃欲试的时候，总会提出几个？，它是什么（What）？为什么要用它（Why）？怎样学习它（How）？作为开放源码运动的主要组成部分，Linux的应用越来越广泛，从我们平时的娱乐、学习，到商业、政府办公，再到大规模计算的应用。为了满足人们的需求，各种各样的、基于Linux的应用软件层出不穷。只要具备了LinuX的基本功，并具有了自学的能力之后，都可以通过长期地学习予以掌握。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">2．从命令开始、从基础开始</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">常常有些朋友一接触Linux就希望构架网站，根本没有想到要先了解一下Linux的基础。这是相当困难的。虽然Linux桌面应用发展很快，但是命令在Linux中依然有很强的生命力。Linux是一个命令行组成的操作系统，精髓在命令行，无论图形界面发展到什么水平这个原理是不会变的。Linux命令有许多强大的功能：从简单的磁盘操作、文件存取、到进行复杂的多媒体图象和流媒体文件的制作。这里笔者把它们中比较重要的和使用频率最多的命令，按照它们在系统中的作用分成几个部分介绍给大家，通过这些基础命令的学习，我们可以进一步理解Linux系统。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">3．选择一本好的Linux书籍</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">无论在论坛还是读者反馈中，我们看到最多的问题往往是某个新手，在安装或使用Linux的过程中遇到一个具体的问题就开始提问，很多都是重复性的问题，甚至有不少人连基本的问题描述都不是很清楚。这说明很多初学Linux的人还没有掌握基本功。怎样才能快速提高掌握Linux的基本功呢?最有效的方法莫过于学习权威的Linux工具书，工具书对于学习者而言是相当重要的。一本错误观念的工具书却会让新手整个误入歧途。目前国内关于Linux的书籍有很多不过精品的不多，笔者强烈建议阅读影印本的o'reilly原版Linux图书http://www.oreilly.com.cn/，而且出版社还提供了一个非常好的路线图：linux.php"&gt;http://www.oreilly.com.cn/guide/guide_linux.php</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">4．养成在命令行下工作的习惯</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">一定要养成在命令行下工作的习惯，要知道X－window只是运行在命令行模式下的一个应用程序。在命令行下学习虽然一开始进度较慢，但是熟悉后，你未来的学习之路将是以指数增加的方式增长的。对网管员来说，命令行实际上就是规则，它总是有效的，同时也是灵活的。即使是通过一条缓慢的调制解调器线路，它也能操纵几千公里以外的远程系统。 5．用UNIX思维思考Linux</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">由于Linux是参照UNIX的思想来设计的，理解和掌握它就必须以Unix的思维来进行，而不能以Windows思维。不可否认，Windows在市场上的成功很大一部分在于技术思想的独到之处。可是这个创新是在面对个人用户的前提下进行的，而面对着企业级的服务应用，它还是有些力不从心。多年来在计算机操作系统领域一直是二者独大：UNIX在服务器领域，Windows在个人用户领域。由此可见，用户需求决定了所采用的操作系统。不管什么原因，如果要学习Linux，那么首先要将思维从Windows的"这个小河"中拖出来，放入UNIX的海洋。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">6．学习Shell</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">对于Shell（中文名称壳），习惯Windows的读者肯定是非常陌生的，因为Windows只有一个"Shell"（如果可以说是Shell的话），那就是Windows自己。用一句话容易理解的解释就是，shell是用户输入命令与系统解释命令之间的中介。最直观的说法，一种Shell有一套自己的命令。举一个容易理解的例子，Linux的标准Shell是Bash Shell；Solaris的shell是B shell；Linux的Shell是以命令行的方式表现出来的。读者可能会不理解，Windows从命令行"进化"到了图形界面，那么Linux现在还使用命令行岂不是一种倒退?当初我刚刚接触Linux时就曾有过这种想法。可是后来发现，如果使用图形界面，那么分配给应用软件的资源就少了，在价格昂贵的服务器上，能够以较低的硬件配置实现同样的功能是非常重要的。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">下面举例说明：一台服务器有1GB内存，假设其中512MB用于处理图形界面，若要安装一个需要784MB内存的数据库软件，唯一的办法就是扩大内存。但是如果使用命令行，系统可能只需要64MB内存，其他的内存就可以供数据库软件使用了。使用命令行，不仅是内存，而且CPU及硬盘等资源的占用都要节省很多。所以，作为服务器，使用命令行是优点而不是缺点。既然Shell有这么多优点，就必须要学习它。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">7．勤于实践</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">要增加自己Linux的技能，只有通过实践来实现了。所以，赶快找一台计算机，赶快安装一个Linux发行版本，然后进入精彩的Linux世界。相信对于你自己的Linux能力必然大有斩获。此外，人脑不像计算机的硬盘一样，除非硬盘坏掉了或者是资料被你抹掉了，否则存储的资料将永远而且立刻地记忆在硬盘中。在人类记忆的曲线中，你必须要不断地重复练习才会将一件事情记得比较熟。学习Linux也一样，如果你无法经常学习的话，学了后面的，前面的往往忘了。对Linux命令熟悉后，可以开始搭建一个小的Linux网络，这是最好的实践方法。Linux是网络的代名词，Linux网络服务功能非常强大，不论是邮件服务器、Web服务器、DNS服务器等都非常完善。当然你不需搭建所有服务，可以慢慢来。需要说明的是这个Linux网络对于初学者有两三台计算机即可。自己多动手，不要非要等着别人帮你解决问题。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">8．学会使用文档</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">和私有操作系统不同，各个Linux的发行版本的技术支持时间都较短，这对于Linux初学者是往往不够的。其实当你安装了一个完整的Linux系统后，其中已经包含了一个强大的帮助系统，只是可能你还没有发现和使用它们的技巧。主流Linux发行版都自带非常详细的文档（包括手册页和FAQ），从系统安装到系统安全，针对不同层次的人的详尽文档，仔细阅读文档后40%问题都可在此解决。查阅经典工具书和Howto，特别是Howto是全球数以万计的Linux、UNIX的经验总结非常有参考价值，通常40%的问题可以解决。安装一个新的软件时先看README，再看INSTALL然后看FAQ，最后才动手安装，这样遇到问题就知道为什么了。如果说明文档不看，结果出了问题再去论坛来找答案反而浪费时间。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">当查找文档时，一定要看文档是在何种版本、何种环境及何种状态下出现的何种结果。对于文档的有效性，一时还无法在操作前就知道结论如何，那么对某个专题或问题，阅读相关的多篇文章将会节省大量的时间，还可以保证尽量"干净"的环境，有效避免因为不同操作所造成的更多问题。操作时要仔细核对各个步骤及输出的结果，尽量保持与文档一致。 9．在Linux论坛获取帮助</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">如果上面的措施没有解决问题，此时你就需要Linux社区的帮助了。需要说明的是你要有周全的思考，准备好你的问题，不要草率的发问，否则只会得到到草率的回答或者根本得不到任何答案。越表现出在寻求帮助前为解决问题付出的努力，你越能得到实质性的帮助。最好先搜寻一下论坛是否有你需要的文章。这样可以获得事半功倍的效果。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">你需要提供精确有效的信息。这并不是要求你简单的把成吨的出错代码或者数据完全转储摘录到你的提问中。如果你有庞大而复杂的测试条件，尽量把它剪裁得越小越好。可能你会遇到这种情况，对于一个问题会出现不同内容回答，这时你需要通过实践来验证。另外把这个问题放在其他Linux社区请求帮助也是一种选择。如果得不到答案，请不要以为我们觉得无法帮助你。有时只是看到你问题的人不知道答案罢了。这时换一个社区是不错的选择。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">10．学习专业英文</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">如果你想深入学习Linux，看不懂文档，因为实在是太难了。写得最好的，最全面的文档都是英语写的，最先发布的技术信息也都是用英语写的。即便是非英语国家的人发布技术文档，也都首先翻译成英语在国际学术杂志和网络上发表。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">通过man、info等命令，可以从在线帮助中快速地获得所需要的命令和操作方法。不要害怕海量的系统帮助，仔细阅读几个man或info文档就会发现，这些帮助几乎都按照固定格式写成命令名称、参数、参数说明、使用例子、参考等。当英语成为一种习惯，就会自觉地查找或订阅互联网上感兴趣的英文材料。这样，在不知不觉中就已经和世界同步了。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">11．在社区共享你的经验</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">随着Linux应用的扩展，出现了不少Linux社区。其中有一些非常优秀的社区：水木清华、其中有一些非常优秀的社区：www.linuxforum.net（国内最高水平GNU站点）、http://www.chinaunix.net/（中国最大的Unix技术社区），随着知识的不断积累，就可以把自己动手解决一些前人没有遇到的问题写出文档在网络上共享给其他读者。这个时候，也就成为了一名"高手"。Linux的使用者一般都是专业人士，他们有着很好的电脑背景且愿意协助他人，Linux高手更具有鼓励新手的文化精神。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">最后是笔者的Linux学习的一个路线图（roadmap）：</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">了解Linux的基础知识，这些包含了用户管理、群组的概念、权限的观念等；</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">掌握100个以上的常用命令；</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">掌握.tgz、.rpm等软件包的常用安装方法</span></div><div><span style="font-size: 12px;"><br /></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;">熟悉Linux文件系统和目录结构。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">掌握vi,gcc,gdb等常用编辑器，编译器，调试器。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">理解shell别名、管道、I/O重定向、输入和输出及shell脚本编程。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">网络的基础包括：掌握路由概念、OSI七层网络模型、TCP/IP模型及相关服务对应的层次对于Linux学习非常重要的。然后学习Linux环境下的组网。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">以上是Linux学习方法，希望对你有些帮助。</span></div><img src ="http://www.cppblog.com/zhenglinbo/aggbug/178103.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zhenglinbo/" target="_blank">hoshelly</a> 2012-06-08 18:18 <a href="http://www.cppblog.com/zhenglinbo/archive/2012/06/08/178103.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>