Linux多任务: exec 和fork()的联用
2013-11-21 10:27
387 查看
系统调用exec 和fork()联合起来为程序员提供了强有力的功能。我们可以先用fork()建立子进程,然后在子进程中使用exec,这样就实现了父进程运行一个与其不同的子进程,并且父进程不会被覆盖。
下面我们给出一个exec 和fork()联用的例子,从中我们可以清楚的了解这两个系统调用联用的细节。其程序清单如下:
在程序中,在调用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 的调用。程序清单如下:
docommand 并没有通过exec 去直接执行指定的命令,而是通过exec 去执行shell(即/bin/sh),并由shell 再执行指定的命令。这是一种非常巧妙的方法,它使得docommand 能使用shell 提供的一系列特性(如文件名扩展等)。在引用shell 中使用的参数-c,表示从下一个参数中取得命令名,而不是从标准输入上取得。
下面我们给出一个exec 和fork()联用的例子,从中我们可以清楚的了解这两个系统调用联用的细节。其程序清单如下:
#include <stdio.h> #include <unistd.h> main() { int pid; /* fork 子进程 */ pid=fork(); switch(pid) { case -1: perror("fork failed"); exit(1); case 0: execl("/bin/ls","ls","-l","--color",NULL); perror("execl failed"); exit(1); default: wait(NULL); printf("ls completed\n"); exit(0); } }
在程序中,在调用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 的调用。程序清单如下:
int docommand(char* command) { int pid; switch(pid=fork()) { case -1: return -1; case 0: execl("/bin/sh","sh","-c",command,NULL); exit(127); default: wait(NULL); } return 0; }
docommand 并没有通过exec 去直接执行指定的命令,而是通过exec 去执行shell(即/bin/sh),并由shell 再执行指定的命令。这是一种非常巧妙的方法,它使得docommand 能使用shell 提供的一系列特性(如文件名扩展等)。在引用shell 中使用的参数-c,表示从下一个参数中取得命令名,而不是从标准输入上取得。
相关文章推荐
- Linux驱动***_init()宏调用的先后顺序
- Linux 进程、进程组、会话周期、控制终端
- linux下设置目录同步NFS——实现文件共享
- Linux下用户和文件(或是目录)的关系
- linux下listener.ora文件属于不同用户时使用注意点
- linux 系统编程整理
- linux 文件重定向总结
- Linux系统日志的介绍
- centos下读取某个文件的头几行或末几行 (head 、tail)
- linux前后台进程切换(转)
- Linux 命令行快捷键
- CentOS编译Hadoop 2.2.0 Pass 总结
- Linux 上面部署 Jboss 6.1.0.Fina
- LINUX 环境变量
- Linux Platform Device and Driver
- Linux 输出重定向>和>>的区别
- Linux 输出重定向>和>>的区别
- Linux系统下的头文件
- THE META KEY
- Linux进程地址空间的一步步探究