进程回收

在Unix/Linux下进行多进程编程很常见,一般来讲,进程终止自身有两种方式:

向exit传递的参数以及从main返回的值最终都会传递给操作系统,操作系统此时并不会销毁该进程,直到把这些值传递给产生该进程的父进程,处于这种状态下的进程称为僵尸进程。

如何向父进程传递值呢?操作系统不会主动把这些值传给父进程,在有父进程通过wait/waitpid调用主动来取时,操作系统才会传递该值。换言之,如果父进程未主动要求获得子进程的结束状态,操作系统将一直保留,并让子进程长时间处于僵尸状态。

如果在进程退出时,其父进程已经结束,那么init进程将自动接手该进程为子进程。

小结

等待子进程接口

#include <sys/wait.h>
pid_t wait(int *statloc);
pid_t waitpid(pid_t pid, int *statloc, int options);

说明:

信号回收子进程

如果父进程较忙,不能一直阻塞或者轮询去等子进程退出,可以通过信号做到事件驱动。

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
void WaitChild(int sig)
{
    int status;
    pid_t pid = waitpid(-1, &status, WNOHANG);
    if (WIFEXITED(status))
        printf("process %d exited with %d\n", pid, WEXITSTATUS(status));
}
int main()
{
    pid_t pid;
    struct sigaction act;

    act.sa_handler = WaitChild;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    sigaction(SIGCHLD, &act, 0);

    pid = fork();
    if (pid == 0) {
        puts("this is child process 1");
        sleep(3);
        return 12;
    } else {
        printf("child1 id: %d\n", pid);
        pid = fork();
        if (pid == 0) {
            puts("thils is child process 2");
            sleep(5);
            exit(5);
        } else {
            printf("child2 id: %d\n", pid);
            for(;;sleep(3));
        }
    }
    return 0;
}
Table of Contents