百度网站说明书,wordpress 嵌入字体,外包公司网络安全管理制度,wordpress 排除置顶文章文章目录 一、进程退出1.1、进程正常退出方式1.2、异常退出 二、父进程等待子进程退出#xff08;一#xff09;2.1、为什么要等待子进程退出2.2、#xff08;1#xff09;父进程等待子进程退出并收集子进程的退出状态如何等待wstatus空wstatus非空 2.3、#xff08;2一2.1、为什么要等待子进程退出2.2、1父进程等待子进程退出并收集子进程的退出状态如何等待wstatus空wstatus非空 2.3、2子进程退出状态不被收集变成僵尸进程僵死进程。vfork没有使用wait退出状态不被收集子进程变成僵尸进程fork没有使用wait退出状态不被收集子进程变成僵尸进程 三、父进程等待子进程退出二3.1、相关函数阻塞等待非阻塞等待 3.2、孤儿进程面s 一、进程退出
vfork保证子进程先运行当子进程退出后父进程才运行。
1.1、进程正常退出方式
共5种退出方式
main函数调用return进程调用exit()标准c库进程调用_exit()或者_Exit()属于系统调用
补充
进程最后一个线程返回最后一个线程调用pthread_exit 1.2、异常退出
主动调用abort()放弃当前进程当进程收到某些信号时如ctrlC【ctrlZ???挂起】最后一个进程对取消cancellation请求做出相应
不管进程如何终止最后都会执行内核中同一段代码。这段代码为响应进程关闭素有打开的描述符释放它所使用的存储器。 对上述任意一种终止情形我们都希望终止进程能够通知其父进程它是如何终止的。对于三个终止函数exit、_exit、_Exit实现这一点的方法是将其退出状态传递exit status作为参数传递给函数。 在异常终止情况下内核不是进程本身产生一个指示其异常终止原因的一个状态termination status。在任意一种情况下该终止进程的父进程都能调用wait或waitpid函数取得其终止状态。 那么收集退出状态无非就是给exit函数传递一个值。建议使用exit是对_exit或_Exit的封装会对进程的缓冲区做些处理而_exit或_Exit系统调用是直接退出。
#include sys/types.h
#include unistd.h
#include stdio.h
#include stdlib.hint main()
{pid_t pid;int cnt 0;pid vfork();if(pid 0){while(1){printf(cnt%d\n, cnt);printf(this is father process, pid:%d\n,getpid());sleep(1);}}else if(pid 0){while(1){printf(this is chlid process, pid:%d\n,getpid());sleep(1);cnt;if(cnt 3){_Exit(0);//break;}}}return 0;
}
二、父进程等待子进程退出一
2.1、为什么要等待子进程退出
问创建子进程的目的是什么创建子进程的目的是为了让子进程干活那么子进程不一定能把交给它的活顺利都做完。所以我们比较关心子进程干没干完活干的怎么样。所以我们要等待子进程的退出并且收集退出的状态。我不仅要等待子进程的退出而且还要检测你这个活干的怎么样。 你正常退出你活干到什么程度根据exit的退出码的不同进程判断。你没干完是异常退出你是不想干了还是其它原因ctrlC了等等。这是父进程为什么要等待子进程的退出的原因。
2.2、1父进程等待子进程退出并收集子进程的退出状态
调用wait函数解析返回状态码。子进程调用exit返回状态码。调用wait可以防止子进程变成僵尸进程。 如何等待
使用wait函数函数参数是一个地址 wstatus参数是一个整型数指针wstatus非空子进程退出状态放在它所指向的地址中。wstatus空不关心退出状态。
wstatus空
父进程中使用了wait函数就不会出现子进程变成僵尸进程的情况。
#include sys/types.h
#include sys/wait.h
#include unistd.h
#include stdio.h
#include stdlib.hint main()
{pid_t pid;int cnt 0;pid fork();if(pid 0){wait(NULL);while(1){printf(cnt%d\n, cnt);printf(this is father process, pid:%d\n,getpid());sleep(1);}}else if(pid 0){while(1){printf(this is chlid process, pid:%d\n,getpid());sleep(1);cnt;if(cnt 5){exit(0);}}}return 0;
} wstatus非空
非空检查退出状态存在status里面
#include sys/types.h
#include sys/wait.h
#include unistd.h
#include stdio.h
#include stdlib.hint main()
{pid_t pid;int cnt 0;int status 10;pid fork();if(pid 0){wait(status);printf(chlid quit, chlid status:%d\n, WEXITSTATUS(status));while(1){printf(cnt%d\n, cnt);printf(this is father process, pid:%d\n,getpid());sleep(1);}}else if(pid 0){while(1){printf(this is chlid process, pid:%d\n,getpid());sleep(1);cnt;if(cnt 5){exit(3);}}}return 0;
}
2.3、2子进程退出状态不被收集变成僵尸进程僵死进程。
vfork没有使用wait退出状态不被收集子进程变成僵尸进程
没有使用wait退出状态不被收集
#include sys/types.h
#include unistd.h
#include stdio.h
#include stdlib.hint main()
{pid_t pid;int cnt 0;pid vfork();if(pid 0)//父进程{while(1){printf(cnt%d\n, cnt);printf(this is father process, pid:%d\n,getpid());sleep(1);}}else if(pid 0){while(1){printf(this is chlid process, pid:%d\n,getpid());sleep(1);cnt;if(cnt 3){exit(0);//break;}}}return 0;
}使用ps查看进程S 是正在运行的状态Z 是僵尸进程 zombie fork没有使用wait退出状态不被收集子进程变成僵尸进程
fork 父进程没有wait同样子进程执行结束父进程没收集其退出状态变为了僵尸进程
#include sys/types.h
#include unistd.h
#include stdio.h
#include stdlib.hint main()
{pid_t pid;int cnt 0;pid fork();if(pid 0){while(1){printf(cnt%d\n, cnt);printf(this is father process, pid:%d\n,getpid());sleep(1);}}else if(pid 0){while(1){printf(this is chlid process, pid:%d\n,getpid());sleep(1);cnt;if(cnt 5){exit(0);}}}return 0;
}
三、父进程等待子进程退出二
3.1、相关函数 如果其所有子进程都在执行则阻塞如果一个子进程已终止正等待父进程获取其终止状态则取得该子进程的终止状态立即返回如果它没有任何子进程则立即出错返回
对于waitpid函数中几个参数解释如下
pid -1 等待任意子进程。就这一方面而言waitpid与wait等效。pid 0 等待其进程ID与pid相等的子进程。pid 0 等待其组ID等于调用进程组ID的任一子进程。pid -1 等待其组ID等于pid绝对值的任一子进程。
status参数是一个整型数指针非空子进程退出状态放在它所指向的地址中。空不关心退出状态
阻塞等待
阻塞等待不会出现僵尸进程情况 #include sys/types.h
#include sys/wait.h
#include unistd.h
#include stdio.h
#include stdlib.hint main()
{pid_t pid;int cnt 0;int status 10;pid fork();if(pid 0){wait(status);//阻塞等待printf(chlid quit, chlid status:%d\n, WEXITSTATUS(status));while(1){printf(cnt%d\n, cnt);printf(this is father process, pid:%d\n,getpid());sleep(1);}}else if(pid 0){while(1){printf(this is chlid process, pid:%d\n,getpid());sleep(1);cnt;if(cnt 3){exit(3);}}}return 0;
}非阻塞等待
非阻塞se等待子进程也会变成僵尸进程实验证明。而且waitpid马上打印好像不关心子进程所以使用不多。一般使用wait。
#include sys/types.h
#include sys/wait.h
#include unistd.h
#include stdio.h
#include stdlib.hint main()
{pid_t pid;int cnt 0;int status 10;pid fork();if(pid 0){//wait(status);waitpid(pid, status, WNOHANG);//非阻塞等待printf(chlid quit, chlid status:%d\n, WEXITSTATUS(status));while(1){printf(cnt%d\n, cnt);printf(this is father process, pid:%d\n,getpid());sleep(1);}}else if(pid 0){while(1){printf(this is chlid process, pid:%d\n,getpid());sleep(1);cnt;if(cnt 3){exit(3);}}}return 0;
} 3.2、孤儿进程面s
父进程不等待子进程退出在子进程结束之前就结束了自己的“生命”此时子进程叫做孤儿进程。Linux避免系统存在过多孤儿进程init进程收留孤儿进程变成孤儿进程的父进程。init进程ID为1实验验证
#include sys/types.h
#include sys/wait.h
#include unistd.h
#include stdio.h
#include stdlib.hint main()
{pid_t pid;int cnt 0;int status 10;pid fork();if(pid 0){printf(this is father process, pid:%d\n,getpid());}else if(pid 0){while(1){printf(chlid pid:%d, my father pid:%d\n,getpid(), getppid());sleep(1);cnt;if(cnt 5){exit(3);}}}return 0;
}这里父进程退出后新的父进程的进程id为1468而不是1。 是因为这里是在图形界面伪终端运行的shell其实是init进程的一个子进程故孤儿进程其实是被shell所收养 在字符化界面运行时ppid就是1了。