Waitpid equivalent with timeout?

前端 未结 10 1252
小鲜肉
小鲜肉 2020-11-27 12:10

Imagine I have a process that starts several child processes. The parent needs to know when a child exits.

I can use waitpid, but then if/when the paren

10条回答
  •  渐次进展
    2020-11-27 12:58

    Don't mix alarm() with wait(). You can lose error information that way.

    Use the self-pipe trick. This turns any signal into a select()able event:

    int selfpipe[2];
    void selfpipe_sigh(int n)
    {
        int save_errno = errno;
        (void)write(selfpipe[1], "",1);
        errno = save_errno;
    }
    void selfpipe_setup(void)
    {
        static struct sigaction act;
        if (pipe(selfpipe) == -1) { abort(); }
    
        fcntl(selfpipe[0],F_SETFL,fcntl(selfpipe[0],F_GETFL)|O_NONBLOCK);
        fcntl(selfpipe[1],F_SETFL,fcntl(selfpipe[1],F_GETFL)|O_NONBLOCK);
        memset(&act, 0, sizeof(act));
        act.sa_handler = selfpipe_sigh;
        sigaction(SIGCHLD, &act, NULL);
    }
    

    Then, your waitpid-like function looks like this:

    int selfpipe_waitpid(void)
    {
        static char dummy[4096];
        fd_set rfds;
        struct timeval tv;
        int died = 0, st;
    
        tv.tv_sec = 5;
        tv.tv_usec = 0;
        FD_ZERO(&rfds);
        FD_SET(selfpipe[0], &rfds);
        if (select(selfpipe[0]+1, &rfds, NULL, NULL, &tv) > 0) {
           while (read(selfpipe[0],dummy,sizeof(dummy)) > 0);
           while (waitpid(-1, &st, WNOHANG) != -1) died++;
        }
        return died;
    }
    

    You can see in selfpipe_waitpid() how you can control the timeout and even mix with other select()-based IO.

提交回复
热议问题