/*** 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 ", getpid(), getgid()); // pid_t pid = waitpid(q, NULL, WNOHANG); // pid_t pid = wait(NULL); // printf("child pid = %d ", 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 ", pid, status); printf("WEXITSTATUS(status) = %d ", WEXITSTATUS(status)); //获取退出值 printf("WIFEXITED(status) = %d ", WIFEXITED(status)); //判断是否正常推出 printf("WIFSIGNALED(status) = %d ", WIFSIGNALED(status)); //判断是否被杀死 set.erase(it++); } else { printf("pid still alive: %d ", pid); ++it; } // if (kill(pid, 0) != -1) { // printf("pid still alive: %d", pid); // ++it; // } else { // printf("pid not alive, prepare for clean: %d ", pid); // } } sleep(1); } } else { sleep(i); printf("I'm %dth child, pid = %d, gpid=%d ", 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; }