Linux多任务: exec 和fork()的联用

  系统调用exec 和fork()联合起来为程序员提供了强有力的功能。我们可以先用fork()建立子进程,然后在子进程中使用exec,这样就实现了父进程运行一个与其不同的子进程,并且父进程不会被覆盖。
  下面我们给出一个exec 和fork()联用的例子,从中我们可以清楚的了解这两个系统调用联用的细节。其程序清单如下:

 1 #include <stdio.h>
 2 #include <unistd.h>
 3 main()
 4 {
 5 int pid;
 6 /* fork 子进程 */
 7 pid=fork();
 8 switch(pid) {
 9 case -1:
10 perror("fork failed");
11 exit(1);
12 case 0:
13 execl("/bin/ls","ls","-l","--color",NULL);
14 perror("execl failed");
15 exit(1);
16 default:
17 wait(NULL);
18 printf("ls completed\n");
19 exit(0);
20 }
21 }

  在程序中,在调用fork()建立一个子进程之后,马上调用了wait(),使父进程在子进程结束之前,一直处于睡眠状态。所以,wait()向程序员提供了一种实现进程之间同步的简单方法,我们将在下面对它作出更详细的讨论。

  为了说明得更清楚一些,我们用图3-3 来解释程序的工作。图3-3 分为fork()调用前、fork()调用后和exec 调用后三个部分。

 

 

图1 exec()和fork()的联用

 

  在fork()调用前,只有一个进程A,PC 指向将要执行的下一个语句。fork()调用后,就有了进程A 和进程B。A 是父进程,它正在执行系统调用wait(),使进程A 睡眠,直至进程B 结束。同时,B 正在用exec 装入命令ls。exec 调用后,进程B 的程序被ls 的代码取代,这时执行ls 命令的代码。进程B 的PC 指向ls 的第一个语句。由于A 正在等待B 的结束,所以它的PC 所指位置未变。
  现在我们应该了解命令解释程序shell 的工作概况。当shell 从命令行接受到以正常方式(即前台运行)执行一个命令或程序的要求时,它就按上述方法调用fork()、exec 和ait(),以实现命令或程序的执行。当要求在后台执行一个命令或程序时,shell 就省略对wait 的调用,使得shell 和命令进程并发运行。

  为了帮助读者进一步熟悉和掌握fork()和exec 的使用,我们再来看一个名为docommand的程序,这个程序仿真Linux 库调用system() ,它可以在程序中执行一个shell 命令。docommand 的主题是对fork()和exec 的调用。程序清单如下:

 1 int docommand(char* command)
 2 {
 3 int pid;
 4 switch(pid=fork())
 5 {
 6 case -1:
 7 return -1;
 8 case 0:
 9 execl("/bin/sh","sh","-c",command,NULL);
10 exit(127);
11 default:
12 wait(NULL);
13 }
14 return 0;
15 }

docommand 并没有通过exec 去直接执行指定的命令,而是通过exec 去执行shell(即/bin/sh),并由shell 再执行指定的命令。这是一种非常巧妙的方法,它使得docommand 能使用shell 提供的一系列特性(如文件名扩展等)。在引用shell 中使用的参数-c,表示从下一个参数中取得命令名,而不是从标准输入上取得。

 

转载于:https://www.cnblogs.com/huazhen/p/3435055.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值