⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 00000003.htm

📁 一份很好的linux入门资料
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<HTML><HEAD>  <TITLE>BBS水木清华站∶精华区</TITLE></HEAD><BODY><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER>发信人:&nbsp;reden&nbsp;(Offer&nbsp;快快来啊&nbsp;~!),&nbsp;信区:&nbsp;Linux&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>标&nbsp;&nbsp;题:&nbsp;Linux程式设计入门&nbsp;-&nbsp;fork,&nbsp;pthread,&nbsp;and&nbsp;signals&nbsp;<BR>发信站:&nbsp;BBS&nbsp;水木清华站&nbsp;(Thu&nbsp;Apr&nbsp;&nbsp;1&nbsp;19:57:47&nbsp;1999)&nbsp;<BR>&nbsp;<BR>Linux程式设计入门&nbsp;-&nbsp;fork,&nbsp;pthread,&nbsp;and&nbsp;signals&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;在UNIX程式设计中,学会fork及signal的运用,算是相当基本的功夫。&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;fork()及signal经常运用在daemon守护神这一类常驻程式,另外像&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;a4c.tty/yact/chdrv这些中文终端机程式也有用到,一般如&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;Mozilla/Apache/Squid等大程式几乎都一定会用到。&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;虽然在UNIX下的程式写作,对thread的功能需求并非很大,但thread在现代的&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;作业系统中,几乎都已经存在了。pthread是Linux上的thread函数库,如果您&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;要在Linux下撰写多线程式,例如MP3播放程式,熟悉pthread的用法是必要的。&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;pthread及signal都可以用一大章来讨论。在这里,我只谈及最简单及常用的技&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;巧,当您熟悉这些基本技巧的运用後,再找一些专门深入探讨pthread及signal&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;程式写作的书籍来研究。这些进阶的写法,用到的机会较少,将层次分明,学&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;习速度应该会比较快。&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;程序分歧fork()&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;fork()会产生一个与父程序相同的子程序,唯一不同之处在於其process&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;id(pid)。&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;如果我们要撰写守护神程式,或是例如网路伺服器,需要多个行程来同时提供&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;多个连线,可以利用fork()来产生多个相同的行程。&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;函数宣告&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;pid_t&nbsp;fork(void);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;pid_t&nbsp;vfork(void);&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;返回值:&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;-1&nbsp;:&nbsp;失败。&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;:&nbsp;子程序。&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&gt;0&nbsp;:&nbsp;将子程序的process&nbsp;id传回给父程序。&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;在Linux下fork()及vfork()是相同的东西。&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;范例一:&nbsp;fork.c&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;在这个范例中,我们示范fork()的标准用法。&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;#include&nbsp;&lt;stdio.h&gt;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;#include&nbsp;&lt;stdlib.h&gt;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;#include&nbsp;&lt;unistd.h&gt;&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;void&nbsp;main(void)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;pid_t&nbsp;pid;&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;hello\n&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;pid&nbsp;=&nbsp;fork();&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;switch&nbsp;(pid)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;-1:&nbsp;printf(&quot;failure!\n&quot;);&nbsp;break;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;&nbsp;0:&nbsp;printf(&quot;I&nbsp;am&nbsp;child!\n&quot;);&nbsp;break;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:&nbsp;printf(&quot;my&nbsp;child&nbsp;is&nbsp;%d\n&quot;,pid);&nbsp;break;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(;;)&nbsp;{&nbsp;/*&nbsp;do&nbsp;something&nbsp;here&nbsp;*/&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;编译:&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;gcc&nbsp;-o&nbsp;ex1&nbsp;fork.c&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;执行结果:&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;./ex1&nbsp;&amp;&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;hello&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;my&nbsp;child&nbsp;is&nbsp;8650&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;I&nbsp;am&nbsp;child!&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;我们可以见到,使用fork(),可将一个程式分岐成两个。在分歧之前的程式码&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;只执行一次。&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;检验行程:&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;ps&nbsp;|&nbsp;grep&nbsp;ex1&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;8649&nbsp;&nbsp;p0&nbsp;R&nbsp;&nbsp;&nbsp;&nbsp;0:40&nbsp;./ex1&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;8650&nbsp;&nbsp;p0&nbsp;R&nbsp;&nbsp;&nbsp;&nbsp;0:40&nbsp;./ex1&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;8649是父程序的pid,8650则为子程序的pid。&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;您会需要用到&quot;killall&nbsp;ex1&quot;来杀掉两个行程。&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;范例二:&nbsp;daemon.c&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;在UNIX中,我们一般都利用fork(),来实作所谓的&quot;守护神程式&quot;,也就是DOS中&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;所谓的&quot;常驻程式&quot;。一般的技巧是将父程序结束,而子程序便成为&quot;守护神&quot;。&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;这个范例中,示范一般标准的daemon写法。&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;#include&nbsp;&lt;stdio.h&gt;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;#include&nbsp;&lt;stdlib.h&gt;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;#include&nbsp;&lt;unistd.h&gt;&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;void&nbsp;main(void)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;pid_t&nbsp;pid;&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;pid&nbsp;=&nbsp;fork();&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(pid&gt;0)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;daemon&nbsp;on&nbsp;duty!\n&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(0);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(pid&lt;0)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;Can't&nbsp;fork!\n&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(-1);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(;;)&nbsp;{&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;I&nbsp;am&nbsp;the&nbsp;daemon!\n&quot;);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep(3);&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;do&nbsp;something&nbsp;your&nbsp;own&nbsp;here&nbsp;*/&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;编译:&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;gcc&nbsp;-o&nbsp;ex2&nbsp;daemon.c&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;执行结果:&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;./ex2&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;daemon&nbsp;on&nbsp;duty!&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;I&nbsp;am&nbsp;the&nbsp;daemon!&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;接下来每三秒钟,都会出现一个&quot;I&nbsp;am&nbsp;the&nbsp;daemon!&quot;的讯息,这表示您的程式&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;已经&quot;长驻&quot;在系统中了。&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;检验行程:&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;ps&nbsp;|&nbsp;grep&nbsp;ex2&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;8753&nbsp;&nbsp;p0&nbsp;S&nbsp;&nbsp;&nbsp;&nbsp;0:00&nbsp;./ex2&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;注意到在范例一中,我们下的指令为&quot;./ex1&nbsp;&amp;&quot;,而在范例二中为&quot;./ex2&quot;,没&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;有&quot;&amp;&quot;符号。&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;范例三:&nbsp;lock.c&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;许多的时候,我们希望&quot;守护神&quot;在系统中只有一个,这时候会需要用到pid&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;lock的技巧。如果您注意到/var/run目录中的内容,您会发现到有许多的*.pid&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;档,观看其内容都是一些数字,这些数字其实就是该行程的pid。&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;#include&nbsp;&lt;stdio.h&gt;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;#include&nbsp;&lt;stdlib.h&gt;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;#include&nbsp;&lt;unistd.h&gt;&nbsp;&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;void&nbsp;main(void)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;{&nbsp;&nbsp;<BR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -