杏林好汉 發表於 2023-7-27 00:00:00

Linux 创建子进程执行任务的实现方法

<p>
        <span>linux 操作系统紧紧依赖进程创建来满足用户的需求。例如,只要用户输入一条命令,shell 进程就创建一个新进程,新进程运行 shell 的另一个拷贝并执行用户输入的命令。linux 系统中通过 fork/vfork 系统调用来创建新进程。本文将介绍如何使用 fork/vfork 系统调用来创建新进程并使用 exec 族函数在新进程中执行任务。</span></p>
<p>
        <span><strong>fork 系统调用</strong></span></p>
<p>
        <span>要创建一个进程,最基本的系统调用是 fork:</span></p>
<div class="jb51code">
        <div>
                <div class="syntaxhighlighterxhtml" id="highlighter_32607">
                        <div class="toolbar">
                                <span>?</span>
</div>
                        <table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
                                                        <div class="line number1 index0 alt2">
                                                                1</div>
                                                        <div class="line number2 index1 alt1">
                                                                2</div>
                                                        <div class="line number3 index2 alt2">
                                                                3</div>
                                                </td>
                                                <td class="code">
                                                        <div class="container">
                                                                <div class="line number1 index0 alt2">
                                                                        <code class="xhtml plain"># include &lt;</code><code class="xhtml keyword">unistd.h</code><code class="xhtml plain">&gt;</code>
</div>
                                                                <div class="line number2 index1 alt1">
                                                                        <code class="xhtml plain">pid_t fork(void);</code>
</div>
                                                                <div class="line number3 index2 alt2">
                                                                        <code class="xhtml plain">pid_t vfork(void);</code>
</div>
                                                        </div>
                                                </td>
                                        </tr></tbody></table>
</div>
        </div>
</div>
<p>
        <span>调用 fork 时,系统将创建一个与当前进程相同的新进程。通常将原有的进程称为父进程,把新创建的进程称为子进程。子进程是父进程的一个拷贝,子进程获得同父进程相同的数据,但是同父进程使用不同的数据段和堆栈段。子进程从父进程继承大多数的属性,但是也修改一些属性,下表对比了父子进程间的属性差异:</span></p>
<p>
         </p>
<table border="0"><tbody>
<tr>
<td>
                                <span>继承属性</span>
</td>
                        <td>
                                <span>差异</span>
</td>
                </tr>
<tr>
<td>
                                <span>uid,gid,euid,egid</span>
</td>
                        <td>
                                <span>进程 id</span>
</td>
                </tr>
<tr>
<td>
                                <span>进程组 id</span>
</td>
                        <td>
                                <span>父进程 id</span>
</td>
                </tr>
<tr>
<td>
                                <span>session id</span>
</td>
                        <td>
                                <span>子进程运行时间记录</span>
</td>
                </tr>
<tr>
<td>
                                <span>所打开文件及文件的偏移量</span>
</td>
                        <td>
                                <span>父进程对文件的锁定</span>
</td>
                </tr>
<tr>
<td>
                                <span>控制终端</span>
</td>
                        <td>
                                 </td>
                </tr>
<tr>
<td>
                                <span>设置用户 id 和 设置组 id 标记位</span>
</td>
                        <td>
                                 </td>
                </tr>
<tr>
<td>
                                <span>根目录与当前目录</span>
</td>
                        <td>
                                 </td>
                </tr>
<tr>
<td>
                                <span>文件默认创建的权限掩码</span>
</td>
                        <td>
                                 </td>
                </tr>
<tr>
<td>
                                <span>可访问的内存区段</span>
</td>
                        <td>
                                 </td>
                </tr>
<tr>
<td>
                                <span>环境变量及其它资源分配</span>
</td>
                        <td>
                                 </td>
                </tr>
</tbody></table>
<p>
         </p>
<p>
        <span>下面是一个常见的演示 fork 工作原理的 demo(笔者的环境为 ubuntu 16.04 desktop):</span></p>
<div class="jb51code">
        <div>
                <div class="syntaxhighlighterxhtml" id="highlighter_251079">
                        <div class="toolbar">
                                <span>?</span>
</div>
                        <table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
                                                        <div class="line number1 index0 alt2">
                                                                1</div>
                                                        <div class="line number2 index1 alt1">
                                                                2</div>
                                                        <div class="line number3 index2 alt2">
                                                                3</div>
                                                        <div class="line number4 index3 alt1">
                                                                4</div>
                                                        <div class="line number5 index4 alt2">
                                                                5</div>
                                                        <div class="line number6 index5 alt1">
                                                                6</div>
                                                        <div class="line number7 index6 alt2">
                                                                7</div>
                                                        <div class="line number8 index7 alt1">
                                                                8</div>
                                                        <div class="line number9 index8 alt2">
                                                                9</div>
                                                        <div class="line number10 index9 alt1">
                                                                10</div>
                                                        <div class="line number11 index10 alt2">
                                                                11</div>
                                                        <div class="line number12 index11 alt1">
                                                                12</div>
                                                        <div class="line number13 index12 alt2">
                                                                13</div>
                                                        <div class="line number14 index13 alt1">
                                                                14</div>
                                                        <div class="line number15 index14 alt2">
                                                                15</div>
                                                        <div class="line number16 index15 alt1">
                                                                16</div>
                                                        <div class="line number17 index16 alt2">
                                                                17</div>
                                                        <div class="line number18 index17 alt1">
                                                                18</div>
                                                        <div class="line number19 index18 alt2">
                                                                19</div>
                                                        <div class="line number20 index19 alt1">
                                                                20</div>
                                                        <div class="line number21 index20 alt2">
                                                                21</div>
                                                        <div class="line number22 index21 alt1">
                                                                22</div>
                                                        <div class="line number23 index22 alt2">
                                                                23</div>
                                                        <div class="line number24 index23 alt1">
                                                                24</div>
                                                        <div class="line number25 index24 alt2">
                                                                25</div>
                                                </td>
                                                <td class="code">
                                                        <div class="container">
                                                                <div class="line number1 index0 alt2">
                                                                        <code class="xhtml plain">#include &lt;</code><code class="xhtml keyword">sys</code><code class="xhtml plain">/types.h&gt;</code>
</div>
                                                                <div class="line number2 index1 alt1">
                                                                        <code class="xhtml plain">#include &lt;</code><code class="xhtml keyword">unistd.h</code><code class="xhtml plain">&gt;</code>
</div>
                                                                <div class="line number3 index2 alt2">
                                                                        <code class="xhtml plain">#include &lt;</code><code class="xhtml keyword">stdio.h</code><code class="xhtml plain">&gt;</code>
</div>
                                                                <div class="line number4 index3 alt1">
                                                                        <code class="xhtml plain">#include &lt;</code><code class="xhtml keyword">stdlib.h</code><code class="xhtml plain">&gt;</code>
</div>
                                                                <div class="line number5 index4 alt2">
                                                                        <code class="xhtml plain">int main(void)</code>
</div>
                                                                <div class="line number6 index5 alt1">
                                                                        <code class="xhtml plain">{</code>
</div>
                                                                <div class="line number7 index6 alt2">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">pid_t pid;</code>
</div>
                                                                <div class="line number8 index7 alt1">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">char *message;</code>
</div>
                                                                <div class="line number9 index8 alt2">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">int n;</code>
</div>
                                                                <div class="line number10 index9 alt1">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">pid = fork();</code>
</div>
                                                                <div class="line number11 index10 alt2">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">if(pid &lt; 0)</code>
</div>
                                                                <div class="line number12 index11 alt1">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">{</code>
</div>
                                                                <div class="line number13 index12 alt2">
                                                                        <code class="xhtml spaces">  </code><code class="xhtml plain">perror("fork failed");</code>
</div>
                                                                <div class="line number14 index13 alt1">
                                                                        <code class="xhtml spaces">  </code><code class="xhtml plain">exit(1);</code>
</div>
                                                                <div class="line number15 index14 alt2">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
                                                                <div class="line number16 index15 alt1">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">if(pid == 0)</code>
</div>
                                                                <div class="line number17 index16 alt2">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">{</code>
</div>
                                                                <div class="line number18 index17 alt1">
                                                                        <code class="xhtml spaces">  </code><code class="xhtml plain">printf("this is the child process. my pid is: %d. my ppid is: %d.\n", getpid(), getppid());</code>
</div>
                                                                <div class="line number19 index18 alt2">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
                                                                <div class="line number20 index19 alt1">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">else</code>
</div>
                                                                <div class="line number21 index20 alt2">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">{</code>
</div>
                                                                <div class="line number22 index21 alt1">
                                                                        <code class="xhtml spaces">  </code><code class="xhtml plain">printf("this is the parent process. my pid is %d.\n", getpid());</code>
</div>
                                                                <div class="line number23 index22 alt2">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
                                                                <div class="line number24 index23 alt1">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">return 0;</code>
</div>
                                                                <div class="line number25 index24 alt2">
                                                                        <code class="xhtml plain">}</code>
</div>
                                                        </div>
                                                </td>
                                        </tr></tbody></table>
</div>
        </div>
</div>
<p>
        把上面的代码保存到文件 forkdemo.c 文件中,并执行下面的命令编译:</p>
<div class="jb51code">
        <div>
                <div class="syntaxhighlighterxhtml" id="highlighter_744621">
                        <div class="toolbar">
                                <span>?</span>
</div>
                        <table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
                                                        <div class="line number1 index0 alt2">
                                                                1</div>
                                                </td>
                                                <td class="code">
                                                        <div class="container">
                                                                <div class="line number1 index0 alt2">
                                                                        <code class="xhtml plain">$ gcc forkdemo.c -o forkdemo</code>
</div>
                                                        </div>
                                                </td>
                                        </tr></tbody></table>
</div>
        </div>
</div>
<p>
        然后运行编译出来的 forkdemo 程序:</p>
<div class="jb51code">
        <div>
                <div class="syntaxhighlighterxhtml" id="highlighter_273053">
                        <div class="toolbar">
                                <span>?</span>
</div>
                        <table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
                                                        <div class="line number1 index0 alt2">
                                                                1</div>
                                                </td>
                                                <td class="code">
                                                        <div class="container">
                                                                <div class="line number1 index0 alt2">
                                                                        <code class="xhtml plain">$ ./forkdemo</code>
</div>
                                                        </div>
                                                </td>
                                        </tr></tbody></table>
</div>
        </div>
</div>
<p>
        <span><img title="Linux 创建子进程执行任务的实现方法" alt="Linux 创建子进程执行任务的实现方法" src="https://zhuji.jb51.net/uploads/img/202305/4f4ed18905468afbe459d4c99668e2a5.jpg"></span></p>
<p>
        <span><strong>fork 函数的特点是 "调用一次,返回两次":在父进程中调用一次,在父进程和子进程中各返回一次。</strong>在父进程中返回时的返回值为子进程的 pid,而在子进程中返回时的返回值为 0,并且返回后都将执行 fork 函数调用之后的语句。如果 fork 函数调用失败,则返回值为 -1。</span><br><span>我们细想会发现,fork 函数的返回值设计还是很高明的。在子进程中 fork 函数返回 0,那么子进程仍然可以调用 getpid 函数得到自己的 pid,也可以调用 getppid 函数得到父进程 pid。在父进程中用 getpid 函数可以得到自己的 pid,如果想得到子进程的pid,唯一的办法就是把 fork 函数的返回值记录下来。</span><br><span>注意:执行 forkdemo 程序时的输出是会发生变化的,可能先打印父进程的信息,也可能先打印子进程的信息。</span></p>
<p>
        <span><strong>vfork 系统调用</strong></span></p>
<p>
        <span>vfork 系统调用和 fork 系统调用的功能基本相同。vfork 系统调用创建的进程共享其父进程的内存地址空间,但是并不完全复制父进程的数据段,而是和父进程共享其数据段。为了防止父进程重写子进程需要的数据,父进程会被 vfork 调用阻塞,直到子进程退出或执行一个新的程序。由于调用 vfork 函数时父进程被挂起,所以如果我们使用 vfork 函数替换 forkdemo 中的 fork 函数,那么执行程序时输出信息的顺序就不会变化了。</span></p>
<p>
        <span>使用 vfork 创建的子进程一般会通过 exec 族函数执行新的程序。接下来让我们先了解下 exec 族函数。</span></p>
<p>
        <span><strong>exec 族函数</strong></span></p>
<p>
        <span>使用 fork/vfork 创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往需要调用一个 exec 族函数以执行另外一个程序。当进程调用 exec 族函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的起始处开始执行。调用 exec 族函数并不创建新进程,所以调用 exec 族函数前后该进程的 pid 并不改变。</span></p>
<p>
        <strong><span>exec 族函数一共有六个:</span></strong></p>
<div class="jb51code">
        <div>
                <div class="syntaxhighlighterxhtml" id="highlighter_629929">
                        <div class="toolbar">
                                <span>?</span>
</div>
                        <table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
                                                        <div class="line number1 index0 alt2">
                                                                1</div>
                                                        <div class="line number2 index1 alt1">
                                                                2</div>
                                                        <div class="line number3 index2 alt2">
                                                                3</div>
                                                        <div class="line number4 index3 alt1">
                                                                4</div>
                                                        <div class="line number5 index4 alt2">
                                                                5</div>
                                                        <div class="line number6 index5 alt1">
                                                                6</div>
                                                        <div class="line number7 index6 alt2">
                                                                7</div>
                                                </td>
                                                <td class="code">
                                                        <div class="container">
                                                                <div class="line number1 index0 alt2">
                                                                        <code class="xhtml plain">#include &lt;</code><code class="xhtml keyword">unistd.h</code><code class="xhtml plain">&gt;</code>
</div>
                                                                <div class="line number2 index1 alt1">
                                                                        <code class="xhtml plain">int execl(const char *path, const char *arg, ...);</code>
</div>
                                                                <div class="line number3 index2 alt2">
                                                                        <code class="xhtml plain">int execlp(const char *file, const char *arg, ...);</code>
</div>
                                                                <div class="line number4 index3 alt1">
                                                                        <code class="xhtml plain">int execle(const char *path, const char *arg, ..., char *const envp[]);</code>
</div>
                                                                <div class="line number5 index4 alt2">
                                                                        <code class="xhtml plain">int execv(const char *path, char *const argv[]);</code>
</div>
                                                                <div class="line number6 index5 alt1">
                                                                        <code class="xhtml plain">int execvp(const char *file, char *const argv[]);</code>
</div>
                                                                <div class="line number7 index6 alt2">
                                                                        <code class="xhtml plain">int execve(const char *path, char *const argv[], char *const envp[]);</code>
</div>
                                                        </div>
                                                </td>
                                        </tr></tbody></table>
</div>
        </div>
</div>
<p>
        <span>函数名字中带字母 "l" 的表示其参数个数不确定,带字母 "v" 的表示使用字符串数组指针 argv 指向参数列表。</span><br><span>函数名字中含有字母 "p" 的表示可以自动在环境变量 path 指定的路径中搜索要执行的程序。</span><br><span>函数名字中含有字母 "e" 的函数比其它函数多一个参数 envp。该参数是字符串数组指针,用于指定环境变量。调用这样的函数时,可以由用户自行设定子进程的环境变量,存放在参数 envp 所指向的字符串数组中。</span></p>
<p>
        <span>事实上,只有 execve 是真正的系统调用,其它五个函数最终都调用 execve。这些函数之间的关系如下图所示(此图来自互联网):</span></p>
<p>
        <span><img title="Linux 创建子进程执行任务的实现方法" alt="Linux 创建子进程执行任务的实现方法" src="https://zhuji.jb51.net/uploads/img/202305/09a6d6963dc20446fc365ad2d568edb8.jpg"></span></p>
<p>
        <span>exec 族函数的特征:<strong>调用 exec 族函数会把新的程序装载到当前进程中。在调用过 exec 族函数后,进程中执行的代码就与之前完全不同了,所以 exec 函数调用之后的代码是不会被执行的。</strong></span></p>
<p>
        <span><strong>在子进程中执行任务</strong></span></p>
<p>
        <span>下面让我们通过 vfork 和 execve 函数实现在子进程中执行 ls 命令:</span></p>
<div class="jb51code">
        <div>
                <div class="syntaxhighlighterxhtml" id="highlighter_202786">
                        <div class="toolbar">
                                <span>?</span>
</div>
                        <table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
                                                        <div class="line number1 index0 alt2">
                                                                1</div>
                                                        <div class="line number2 index1 alt1">
                                                                2</div>
                                                        <div class="line number3 index2 alt2">
                                                                3</div>
                                                        <div class="line number4 index3 alt1">
                                                                4</div>
                                                        <div class="line number5 index4 alt2">
                                                                5</div>
                                                        <div class="line number6 index5 alt1">
                                                                6</div>
                                                        <div class="line number7 index6 alt2">
                                                                7</div>
                                                        <div class="line number8 index7 alt1">
                                                                8</div>
                                                        <div class="line number9 index8 alt2">
                                                                9</div>
                                                        <div class="line number10 index9 alt1">
                                                                10</div>
                                                        <div class="line number11 index10 alt2">
                                                                11</div>
                                                        <div class="line number12 index11 alt1">
                                                                12</div>
                                                        <div class="line number13 index12 alt2">
                                                                13</div>
                                                        <div class="line number14 index13 alt1">
                                                                14</div>
                                                        <div class="line number15 index14 alt2">
                                                                15</div>
                                                        <div class="line number16 index15 alt1">
                                                                16</div>
                                                        <div class="line number17 index16 alt2">
                                                                17</div>
                                                        <div class="line number18 index17 alt1">
                                                                18</div>
                                                        <div class="line number19 index18 alt2">
                                                                19</div>
                                                        <div class="line number20 index19 alt1">
                                                                20</div>
                                                        <div class="line number21 index20 alt2">
                                                                21</div>
                                                        <div class="line number22 index21 alt1">
                                                                22</div>
                                                        <div class="line number23 index22 alt2">
                                                                23</div>
                                                        <div class="line number24 index23 alt1">
                                                                24</div>
                                                        <div class="line number25 index24 alt2">
                                                                25</div>
                                                        <div class="line number26 index25 alt1">
                                                                26</div>
                                                        <div class="line number27 index26 alt2">
                                                                27</div>
                                                        <div class="line number28 index27 alt1">
                                                                28</div>
                                                        <div class="line number29 index28 alt2">
                                                                29</div>
                                                        <div class="line number30 index29 alt1">
                                                                30</div>
                                                        <div class="line number31 index30 alt2">
                                                                31</div>
                                                        <div class="line number32 index31 alt1">
                                                                32</div>
                                                        <div class="line number33 index32 alt2">
                                                                33</div>
                                                </td>
                                                <td class="code">
                                                        <div class="container">
                                                                <div class="line number1 index0 alt2">
                                                                        <code class="xhtml plain">#include &lt;</code><code class="xhtml keyword">sys</code><code class="xhtml plain">/types.h&gt;</code>
</div>
                                                                <div class="line number2 index1 alt1">
                                                                        <code class="xhtml plain">#include &lt;</code><code class="xhtml keyword">unistd.h</code><code class="xhtml plain">&gt;</code>
</div>
                                                                <div class="line number3 index2 alt2">
                                                                        <code class="xhtml plain">#include &lt;</code><code class="xhtml keyword">stdio.h</code><code class="xhtml plain">&gt;</code>
</div>
                                                                <div class="line number4 index3 alt1">
                                                                        <code class="xhtml plain">#include &lt;</code><code class="xhtml keyword">stdlib.h</code><code class="xhtml plain">&gt;</code>
</div>
                                                                <div class="line number5 index4 alt2">
                                                                        <code class="xhtml plain">int main(void)</code>
</div>
                                                                <div class="line number6 index5 alt1">
                                                                        <code class="xhtml plain">{</code>
</div>
                                                                <div class="line number7 index6 alt2">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">pid_t pid;</code>
</div>
                                                                <div class="line number8 index7 alt1">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">if((pid=vfork()) &lt; 0)</code>
</div>
                                                                <div class="line number9 index8 alt2">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">{</code>
</div>
                                                                <div class="line number10 index9 alt1">
                                                                        <code class="xhtml spaces">  </code><code class="xhtml plain">printf("vfork error!\n");</code>
</div>
                                                                <div class="line number11 index10 alt2">
                                                                        <code class="xhtml spaces">  </code><code class="xhtml plain">exit(1);</code>
</div>
                                                                <div class="line number12 index11 alt1">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
                                                                <div class="line number13 index12 alt2">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">else if(pid==0)</code>
</div>
                                                                <div class="line number14 index13 alt1">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">{</code>
</div>
                                                                <div class="line number15 index14 alt2">
                                                                        <code class="xhtml spaces">  </code><code class="xhtml plain">printf("child process pid: %d.\n", getpid());</code>
</div>
                                                                <div class="line number16 index15 alt1">
                                                                        <code class="xhtml spaces">  </code><code class="xhtml plain">char *argv[ ]={"ls", "-al", "/home", null}; </code>
</div>
                                                                <div class="line number17 index16 alt2">
                                                                        <code class="xhtml spaces">  </code><code class="xhtml plain">char *envp[ ]={"path=/bin", null};</code>
</div>
                                                                <div class="line number18 index17 alt1">
                                                                        <code class="xhtml spaces">  </code><code class="xhtml plain">if(execve("/bin/ls", argv, envp) &lt; 0)</code>
</div>
                                                                <div class="line number19 index18 alt2">
                                                                        <code class="xhtml spaces">  </code><code class="xhtml plain">{</code>
</div>
                                                                <div class="line number20 index19 alt1">
                                                                        <code class="xhtml spaces">   </code><code class="xhtml plain">printf("subprocess error");</code>
</div>
                                                                <div class="line number21 index20 alt2">
                                                                        <code class="xhtml spaces">   </code><code class="xhtml plain">exit(1);</code>
</div>
                                                                <div class="line number22 index21 alt1">
                                                                        <code class="xhtml spaces">  </code><code class="xhtml plain">}</code>
</div>
                                                                <div class="line number23 index22 alt2">
                                                                        <code class="xhtml spaces">  </code><code class="xhtml plain">// 子进程要么从 ls 命令中退出,要么从上面的 exit(1) 语句退出</code>
</div>
                                                                <div class="line number24 index23 alt1">
                                                                        <code class="xhtml spaces">  </code><code class="xhtml plain">// 所以代码的执行路径永远也走不到这里,下面的 printf 语句不会被执行</code>
</div>
                                                                <div class="line number25 index24 alt2">
                                                                        <code class="xhtml spaces">  </code><code class="xhtml plain">printf("you should never see this message.");</code>
</div>
                                                                <div class="line number26 index25 alt1">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
                                                                <div class="line number27 index26 alt2">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">else</code>
</div>
                                                                <div class="line number28 index27 alt1">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">{</code>
</div>
                                                                <div class="line number29 index28 alt2">
                                                                        <code class="xhtml spaces">  </code><code class="xhtml plain">printf("parent process pid: %d.\n", getpid());</code>
</div>
                                                                <div class="line number30 index29 alt1">
                                                                        <code class="xhtml spaces">  </code><code class="xhtml plain">sleep(1);</code>
</div>
                                                                <div class="line number31 index30 alt2">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">}</code>
</div>
                                                                <div class="line number32 index31 alt1">
                                                                        <code class="xhtml spaces"> </code><code class="xhtml plain">return 0;</code>
</div>
                                                                <div class="line number33 index32 alt2">
                                                                        <code class="xhtml plain">}</code>
</div>
                                                        </div>
                                                </td>
                                        </tr></tbody></table>
</div>
        </div>
</div>
<p>
        把上面的代码保存到文件 subprocessdemo.c 文件中,并执行下面的命令编译:</p>
<div class="jb51code">
        <div>
                <div class="syntaxhighlighterxhtml" id="highlighter_613449">
                        <div class="toolbar">
                                <span>?</span>
</div>
                        <table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
                                                        <div class="line number1 index0 alt2">
                                                                1</div>
                                                </td>
                                                <td class="code">
                                                        <div class="container">
                                                                <div class="line number1 index0 alt2">
                                                                        <code class="xhtml plain">$ gcc subprocessdemo.c -o subprocessdemo</code>
</div>
                                                        </div>
                                                </td>
                                        </tr></tbody></table>
</div>
        </div>
</div>
<p>
        然后运行编译出来的 subprocessdemo程序:</p>
<div class="jb51code">
        <div>
                <div class="syntaxhighlighterxhtml" id="highlighter_714670">
                        <div class="toolbar">
                                <span>?</span>
</div>
                        <table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
                                                        <div class="line number1 index0 alt2">
                                                                1</div>
                                                </td>
                                                <td class="code">
                                                        <div class="container">
                                                                <div class="line number1 index0 alt2">
                                                                        <code class="xhtml plain">$ ./subprocessdemo</code>
</div>
                                                        </div>
                                                </td>
                                        </tr></tbody></table>
</div>
        </div>
</div>
<p>
        <span><img title="Linux 创建子进程执行任务的实现方法" alt="Linux 创建子进程执行任务的实现方法" src="https://zhuji.jb51.net/uploads/img/202305/69266901fa08ad83e8270f07bda51040.jpg"></span></p>
<p>
        <span><strong>总结</strong></span></p>
<p>
        <span>fork/vfork 函数和 exec 族函数都是 linux 系统中非常重要的概念。本文试图通过简单的 demo 来演示这些函数的基本用法,为理解 linux 系统中父进程与子进程的概念提供一些直观的感受。</span></p>
<p>
        原文链接:https://www.cnblogs.com/sparkdev/p/8214455.html</p>
頁: [1]
查看完整版本: Linux 创建子进程执行任务的实现方法