exit _exit wait waitpid
/* #include <stdlib.h> void exit(int status); #include <unistd.h> void _exit(int status); 参数: status:进程退出时的一个状态信息,由调用进程传给父进程 孤儿进程 父进程运行结束,但子进程还在运行,这样的子进程称为孤儿进程 内核会把孤儿进程的父进程设置为init,init会循环的wait()它的已退出的子进程 僵尸进程 终止但未被回收的进程 不能被kill -9 杀死 办法:1、父进程要有义务使用 wait 和 waitpid来回收子进程 2、用ctrl c杀死父进程 用户区的资源可以释放掉,但内核区的资源不能被释放 */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main() { printf("Hello\n"); printf("World"); exit(0); // 会输出Hello\n World // _exit(0); // 只会输出Hello\n 因为exit和\n都会刷新IO缓冲区,_exit()不会 return 0; }
wait
/* wait 和 waitpid 等待子进程结束 功能一样,区别在于wait函数会阻塞,waitpid可以设置不阻塞,且能指定子进程 调用init进程会被挂起,直到一个子进程退出或收到一个不能被忽略的信号 #include <sys/types.h> #include <sys/wait.h> pid_t wait(int *wstatus); 等于 waitpid(-1, &wstatus, 0); pid_t waitpid(pid_t pid, int *wstatus, int options); 参数: pid: < -1 子进程group id等于绝对值的所有进程 == -1 等待所有子进程 == 0 所有子进程group id等于当前调用进程的group id > 0 指定进程 wstatus: 进程退出时的状态信息,传出参数 options: 0:阻塞 其它,如WNOHANG:其余查看手册 返回值: 成功返回子进程id, options = WNOHANG返回0,表示还有子进程 错误返回-1 注意: 一次wait或waitpid调用只能清理一个子进程,清理多个子进程应使用循环 */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main() { // printf("Hello\n"); // printf("World"); // exit(0); // 会输出Hello\n World // // _exit(0); // 只会输出Hello\n 因为exit和\n都会刷新IO缓冲区,_exit()不会 pid_t pid; // 创建5个子进程 for(int i = 0; i < 5; i++) { pid = fork(); if(pid == 0) break; } if(pid > 0) { while(1) { printf("i am parent, pid = %d \n", getpid()); // int ret = wait(NULL); // 通过宏函数判断状态,获取的状态是由子进程的exit()和return传递 int st; int ret = wait(&st); if(WIFEXITED(st)) { printf("状态码为%d\n", WEXITSTATUS(st)); } if(ret == -1) break; printf("wait child %d \n", ret); sleep(1); } } else { printf("i am child, pid = %d \n", getpid()); } return 0; }
自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。