/***
loop_wait.c
***/
#include <bits/stdc++.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
// WARNING: Only signal-safe functions can be used in sig_handler.
// static void sig_handler(int signo) {
// if (signo == SIGCHLD) {
// pid_t pid;
// while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
// }
// }
// signal(signo, sig_handler);
// }
int main(int argc, char *argv[]) {
// signal(SIGCHLD, sig_handler);
int n = 5, i; //默认创建3个子进程
pid_t p, q;
std::set<pid_t> set;
for (i = 0; i < n; i++) { //出口1,父进程专用出口
p = fork();
if (p == 0) {
break; //出口2,子进程出口,i不自增
} else {
set.insert(p);
}
}
if (n == i) {
// sleep(n);
printf("I am parent, pid = %d\n", getpid(), getgid());
// pid_t pid = waitpid(q, NULL, WNOHANG);
// pid_t pid = wait(NULL);
// printf("child pid = %d\n", pid);
while (!set.empty()) {
auto it = set.begin();
while (it != set.end()) {
auto pid = *it;
int status;
if ((waitpid(pid, &status, WNOHANG)) != 0) {
printf("clean OK! pid :%d status: %d\n", pid, status);
printf("WEXITSTATUS(status) = %d\n",
WEXITSTATUS(status)); //获取退出值
printf("WIFEXITED(status) = %d\n",
WIFEXITED(status)); //判断是否正常推出
printf("WIFSIGNALED(status) = %d\n",
WIFSIGNALED(status)); //判断是否被杀死
set.erase(it++);
} else {
printf("pid still alive: %d\n", pid);
++it;
}
// if (kill(pid, 0) != -1) {
// printf("pid still alive: %d", pid);
// ++it;
// } else {
// printf("pid not alive, prepare for clean: %d\n", pid);
// }
}
sleep(1);
}
} else {
sleep(i);
printf("I'm %dth child, pid = %d, gpid=%d\n", i + 1, getpid(), getgid());
if (i == 1) {
abort();
} else if (i == 2) {
std::vector<int> s; // make crush
printf("redeay to crush");
s[10] = 10;
printf("Not crush ??");
} else {
exit(i);
}
}
return 0;
}