此程序是一个类shell程序的简化实现 From:《UNIX环境高级编程》(1-5)
#include "apue.h"
#include <sys/wait.h>
int
main(void)
{
char buf[MAXLINE]; /* from apue.h */
pid_t pid;
int status;
printf("%% "); /* print prompt (printf requires %% to print %) */
while (fgets(buf, MAXLINE, stdin) != NULL) {
if (buf[strlen(buf) - 1] == '/n')
buf[strlen(buf) - 1] = 0; /* replace newline with null */
if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid == 0) { /* child */
execlp(buf, buf, (char *)0);
err_ret("couldn't execute: %s", buf);
exit(127);
}
/* parent */
if ((pid = waitpid(pid, &status, 0)) < 0)
err_sys("waitpid error");
printf("%% ");
}
exit(0);
}
程序和进程
程序是存放在磁盘上、处于某个目录中的一个可执行文件。程序的执行实例被称为进程(process)。某些操作系统用任务(task)表示正在执行的程序。
对于Linux/UNIX系统创建新的进程主要包括如下步骤:
1>使用fork函数创建出新的进程。
特点:一次调用,两次返回。
说明:fork函数用于创建新的进程,所创建的进程为当前进程的子进程。可以通过fork函数的返回值来控制进程是在父进程中还是在子进程中。如果运行在父进程中,则返回的PID为子进程的进程号;如果在子进程中,返回的PID为0。
对于上面的程序假设为进程A,fork函数后又有一进程起名B(B是A的复制)
进程 父进程A 子进程B
返回值 pid = 非负 pid = 0
那么,对于父进程A就不会执行else if中的语句;而子进程Bpid = 0 执行else if。
2>调用exec函数族修改创建的进程。使用fork函数创建的进程是当前运行的完全复制。很多时候,创建新进程的目的是为了运行新的程序,因此,还需要使用exec函数族对创建出的进程修改,让子进程执行新的程序。
Linux系统提供了exec函数族用于对创建新进程中的数据段、代码段和堆栈段进行替换。调用后,进程的进程号保持不变。
此处的execlp()函数如果替换成功,程序的代码段被替换为 buf 从标准输入读入的命令。这就用新的程序文件替换了子进程原先执行的程序文件。如果替换成功,那么就不会执行下面的错误处理。
waitpid()函数
用于根据进程号等待指定的进程。子进程调用execlp执行新程序文件,而父进程希望等待子进程终止,这一要求可以调用waitpid实现。