以一个简单C程序说明
代码运行环境信息:
unbuntu 16.04
C程序功能解释:执行程序中,输入一个linux 指令,并得到linux指令输出结果
#include "apue.h"
#include <sys/wait.h>
int
main(void)
{
char buf[MAXLINE]; /* from apue.h */
pid_t pid;
int status;
printf("------------parent start---------------\n");
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) { /* create a son */
err_sys("fork error");
}else if (pid > 0){
printf("----now is parent \n");
}else if (pid == 0) {
/* child */
printf("----now is son\n");
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");
}else {
printf("--------my son success exit------------\n");
}
printf("%% ");
}
exit(0);
}
运行结果:
root@unbuntu-virtual-machine:/home/unbuntu/001# ./a.out
------------parent start---------------
% who
----now is parent
----now is son
unbuntu tty7 2018-10-11 23:48 (:0)
--------my son success exit------------
% ls
----now is parent
----now is son
a.out error.c hello.c Makefile pid_parent_son.c shell2.c uidgid.c
data getcputc.c ls1.c mycat.c shell1.c testerror.c wirte
--------my son success exit------------
%
以上代码所使用的函数简要说明
①调用pid =fork() 有两种情况,
一种是 在父进程中调用,会直接得到一个大于0的pid值;
另一种是在子进程中调用 pid =fork()(此时不会创建新的子进程,会直接返回一个pid=0的值)
②waitpid是由父进程调用,子进程不会调用该函数(父线程调用来观察子进程情况)
观察上述代码运行结果可得知:
①父进程与子进程执行顺序:第一次执行代码时,父进程首先启动,执行到 pid = fork(),会创建一个子进程,子进程此时开始执行父进程中pid=fork()后续代码逻辑(这表示并不执行父进程所有代码逻辑);
②父进程监控进程:子进程此时已经执行了,父进程为了监控进程(子进程和父进程)运行情况,调用waitpid函数进行监控,在子进程执行过程中,父进程不会消亡,一直处于运行状态,子线程运行完成后,执行waitpid查看当前进程情况
所以每输入一次 指令运行一次结果,就开启了一个子进程
理解难点:不同执行阶段(即不同运行场景阶段),某段代码此时执行对象是谁(子进程还是父进程执行的)
root@unbuntu-virtual-machine:/home/unbuntu/001# ./a.out
------------parent start---------------
% who
----now is parent
----now is son
unbuntu tty7 2018-10-11 23:48 (:0)
--------my son success exit------------
% ls
----now is parent
----now is son
a.out error.c hello.c Makefile pid_parent_son.c shell2.c uidgid.c
data getcputc.c ls1.c mycat.c shell1.c testerror.c wirte
--------my son success exit------------
%
以上 粗体部分表示 父进程运行得来结果,非粗体表示子进程运行得来的