新闻类网站备案,WordPress评论昵称显示错误,如何做外贸网络推广,企业网站的域名是该企业的1.进程退出 子进程退出时#xff1a;父进程帮助子进程回收内核区的资源 exit.c
/*#include stdlib.hvoid exit(int status);#include unistd.hvoid _exit(int status);status参数#xff1a;是进程退出时的一个状态信息。父进程回收子进程资源的时候可以获取…1.进程退出 子进程退出时父进程帮助子进程回收内核区的资源 exit.c
/*#include stdlib.hvoid exit(int status);#include unistd.hvoid _exit(int status);status参数是进程退出时的一个状态信息。父进程回收子进程资源的时候可以获取到。
*/
#include stdio.h
#include stdlib.h
#include unistd.hint main() {printf(hello\n);printf(world);// exit(0);_exit(0);return 0;
}输出结果 刷新缓冲区 \n和fflush(stdout)在这里起的作用是刷新缓冲区 缓冲区刷新的条件 1.进程结束。 2.遇到\n。 3.缓冲区满。 4.手动刷新缓冲区fflush(stdout)。 5.调用exit(0);但是还可以调用_exit(0)不刷新缓冲区。 2.孤儿进程 orphan.c
#include sys/types.h
#include unistd.h
#include stdio.hint main() {// 创建子进程pid_t pid fork();// 判断是父进程还是子进程if(pid 0) {printf(i am parent process, pid : %d, ppid : %d\n, getpid(), getppid());} else if(pid 0) {// 让父进程先die运行完sleep(1);// 当前是子进程printf(i am child process, pid : %d, ppid : %d\n, getpid(),getppid());}// for循环for(int i 0; i 3; i) {printf(i : %d , pid : %d\n, i , getpid());}return 0;
}
输出结果
子进程的父进程id变成init 1
为什么输出时终端会在父进程结束之后在前台出现一下
因为他不知道还有个孤儿进程没执行完毕
3.僵尸进程 zombie.c
子进程die父进程没有去回收子进程的资源
#include sys/types.h
#include unistd.h
#include stdio.hint main() {// 创建子进程pid_t pid fork();// 判断是父进程还是子进程if(pid 0) {while(1) {printf(i am parent process, pid : %d, ppid : %d\n, getpid(), getppid());sleep(1);}} else if(pid 0) {// 当前是子进程printf(i am child process, pid : %d, ppid : %d\n, getpid(),getppid());}// for循环for(int i 0; i 3; i) {printf(i : %d , pid : %d\n, i , getpid());}return 0;
}输出结果
子进程的状态已经变成zombie
如何解决僵尸进程
杀死父进程让子进程被init进程托管
4.wait函数
如何在父进程中回收子进程的资源 wait函数是阻塞状态的父进程中调用了wait函数如果子进程没有结束父进程一直处于阻塞 直到子进程结束了父进程就不阻塞了 wait.c
/*#include sys/types.h#include sys/wait.hpid_t wait(int *wstatus);功能等待任意一个子进程结束如果任意一个子进程结束了此函数会回收子进程的资源。参数int *wstatus进程退出时的状态信息传入的是一个int类型的地址传出参数。返回值- 成功返回被回收的子进程的id- 失败-1 (所有的子进程都结束调用函数失败)调用wait函数的进程会被挂起阻塞直到它的一个子进程退出或者收到一个不能被忽略的信号时才被唤醒相当于继续往下执行如果没有子进程了函数立刻返回返回-1如果子进程都已经结束了也会立即返回返回-1.*/
#include sys/types.h
#include sys/wait.h
#include stdio.h
#include unistd.h
#include stdlib.hint main() {// 有一个父进程创建5个子进程兄弟pid_t pid;// 创建5个子进程// 需要注意不能直接for循环5个fork因为fork产生新的子进程之后会在新的子进程里继续fork// 产生孙子进程进而呈指数级别新增进程// 所以需要判断pid 0时breakfor(int i 0; i 5; i) {pid fork();if(pid 0) {break;}}if(pid 0) {// 父进程while(1) {printf(parent, pid %d\n, getpid());// int ret wait(NULL);int st;//传出参数// 返回值是被回收的子进程的idint ret wait(st);if(ret -1) {break;}if(WIFEXITED(st)) {// 是不是正常退出printf(退出的状态码%d\n, WEXITSTATUS(st));}if(WIFSIGNALED(st)) {// 是不是异常终止printf(被哪个信号干掉了%d\n, WTERMSIG(st));}printf(child die, pid %d\n, ret);sleep(1);}} else if (pid 0){// 子进程while(1) {printf(child, pid %d\n,getpid()); sleep(1); }exit(0);}return 0; // exit(0)
}退出信息相关宏函数 5.waitpid.c
waitpid非阻塞的好处父进程不用一直阻塞可以继续正常做一些业务逻辑等到合适的时机回来检查一下是否有die的子进程需要回收
/*#include sys/types.h#include sys/wait.hpid_t waitpid(pid_t pid, int *wstatus, int options);功能回收指定进程号的子进程可以设置是否阻塞。参数- pid:pid 0 : 某个子进程的pidpid 0 : 回收当前进程组的所有子进程 pid -1 : 回收所有的子进程相当于 wait() 最常用pid -1 : 某个进程组的组id的绝对值回收指定进程组中的子进程比如-2进程组号为2的进程组的子进程- options设置阻塞或者非阻塞0 : 阻塞WNOHANG : 非阻塞- 返回值 0 : 返回子进程的id 0 : optionsWNOHANG, 表示还有子进程活着 -1 错误或者没有子进程了
*/
#include sys/types.h
#include sys/wait.h
#include stdio.h
#include unistd.h
#include stdlib.hint main() {// 有一个父进程创建5个子进程兄弟pid_t pid;// 创建5个子进程for(int i 0; i 5; i) {pid fork();if(pid 0) {break;}}if(pid 0) {// 父进程while(1) {printf(parent, pid %d\n, getpid());sleep(1);int st;// int ret waitpid(-1, st, 0); // 和wait()一样int ret waitpid(-1, st, WNOHANG);if(ret -1) {break;} else if(ret 0) {// 说明还有子进程存在continue;} else if(ret 0) {if(WIFEXITED(st)) {// 是不是正常退出printf(退出的状态码%d\n, WEXITSTATUS(st));}if(WIFSIGNALED(st)) {// 是不是异常终止printf(被哪个信号干掉了%d\n, WTERMSIG(st));}printf(child die, pid %d\n, ret);}}} else if (pid 0){// 子进程// 这里是一个死循环具体通过终端ctrl c杀死子进程的while(1) {printf(child, pid %d\n,getpid()); sleep(1); }exit(0);}return 0;
}进程组