咏月东南 2019-11-10
这里讲解几个在 Linux 操作系统上使用 fork 系统调用。(不定期更新)
一、atexit 函数
void cleanup(void) { printf("Cleaning up\n"); } void fork6() { atexit(cleanup); printf("L0"); fork(); printf("L1"); exit(0); }
运行结果:
int atexit(void (*func)(void)) 函数,当进程正常结束时才会调用 atexit 中的 func 方法,无论你将 func 函数写在哪里。
二、回收子进程
当一个进程由于某种原因终止时,内核并不立即将其从系统中清除。而是会保持在终止的状态等待父进程回收,这称之为 ”僵死进程“ 。当父进程回收已终止的进程时,内核将子进程的退出状态传递给父进程,然后抛弃已终止的进程。至此,该进程不存在。
如果一个父进程终止了,内核会安排 init 进程为它的孤儿进程的养父。
在 64 位系统中,养父的进程号一般不为 1 ,而是一个随机进程号,但是这个进程的 cmd 都是 ”/lib/systemd/systemd --user"/
(使用 ps -ef 命令查看)
1. 子进程先结束,父进程循环挂起。儿子进程正常回收。
void fork7() { if (fork() == 0) { /* Child */ printf("Terminating Child, PID = %d\n", getpid()); exit(0); } else { printf("Running Parent, PID = %d\n", getpid()); while (1) ; /* Infinite loop */ } }
运行结果:
2. 父进程先结束,子进程陷入循环挂起。
void fork8() { if (fork() == 0) { sleep(1); /* Child */ printf("Running Child, PID = %d\n", getpid()); printf("Running Child, PPID = %d\n",getppid()); while (1) ; /* Infinite loop */ } else { printf("Terminating Parent, PID = %d\n", getpid()); exit(0); } }
运行结果:
第二个代码样例中,父进程比子进程先结束运行,此时子进程成为孤儿进程,被收养。养父为前面介绍的进程。
3. 下面有一道对回收子进程有一定参考性的题。
int main(){ int pid1, pid2, pid3, pid4, pid5; printf("1号进程开始\n"); //得到第一个进程的pid pid1 = getpid(); printf("PID1 = %d\n", pid1); //创建第二个进程 pid2 = fork(); if (pid2 == 0) { printf("2号进程开始\n"); printf("PID2 = %d, Parent PID = %d\n", getpid(), getppid()); printf("2号进程结束\n"); //exit退出 exit(0); } //创建第三个进程 pid3 = fork(); if (pid3 == 0) { printf("3号进程开始\n"); printf("PID 3= %d, Parent PID = %d\n", getpid(), getppid()); //在3号进程里面 创建第4个进程 pid4 = fork(); if (pid4 == 0) { printf("4号进程开始\n"); printf("PID 4= %d, Parent PID = %d\n", getpid(), getppid()); //sleep 3 second 等待3号进程结束,自己变成孤儿进程 sleep(3); printf("4号进程结束\n"); exit(0); } //在3号进程里面,创建第5个进程 pid5 = fork(); if (pid5 == 0) { printf("PID 5= %d, Parent PID = %d\n", getpid(), getppid()); printf("5号进程开始\n"); //sleep 3 second 等待3号进程结束,自己变成孤儿进程 sleep(3); printf("5号进程结束\n"); exit(0); } //等待子进程的结束 便于观察pid之间的关系 printf("3号进程结束\n"); exit(0); } //等待子线程的结束 printf("1号进程结束\n"); return 0; } ———————————————— 版权声明:本文为CSDN博主「张谷谷」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/Paulhappy/article/details/50984888
编译代码使用下列命令
$ gcc -o process.out processes.c -lpthread
运行结果如下:
该程序的进程图如下: