Waitpid, эквивалентный с тайм-аутом?

Указатель NULL - это тот, который указывает на никуда. Когда вы разыскиваете указатель p, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p является нулевым указателем, местоположение, хранящееся в p, является nowhere, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception.

В общем, это потому, что что-то не было правильно инициализировано.

47
задан user 15 April 2014 в 00:34
поделиться

4 ответа

Функция может быть прервана сигналом, таким образом, Вы могли установить таймер прежде, чем назвать waitpid (), и это выйдет с EINTR, когда сигнал таймера будет повышен.Править: Это должно быть столь же просто как называющий предупреждение (5) прежде, чем назвать waitpid ().

6
ответ дан Steve Baker 26 November 2019 в 19:33
поделиться

Не смешивайтесь alarm() с wait(). Можно потерять информацию об ошибке тот путь.

Использование прием самоканала. Это превращает любой сигнал в select() способное событие:

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);
}

Затем Ваша подобная waitpid функция похожа на это:

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;
}

Вы видите в selfpipe_waitpid(), как можно управлять тайм-аутом и даже смешаться с другим select() - основывал IO.

42
ответ дан geocar 26 November 2019 в 19:33
поделиться

Если Вы собираетесь использовать сигналы так или иначе (согласно предложению Steve), можно просто отправить сигнал вручную, когда Вы хотите выйти. Это заставит waitpid возвращать EINTR, и поток может тогда выйти. Никакая потребность в периодическом предупреждении/перезапуске.

2
ответ дан Chris Dodd 26 November 2019 в 19:33
поделиться

я могу использовать обработчик сигналов для SIGCHLD, и в обработчике сигналов делают то, что я собирался сделать, когда ребенок выходит, или отправьте сообщение в различный поток, чтобы сделать некоторое действие. Но использование обработчика сигналов запутывает поток кода немного.

для предотвращения условий состязания, необходимо постараться не делать что-либо более сложное, чем изменение энергозависимого флага в обработчике сигналов.

я думаю, что наилучший вариант в Вашем случае состоит в том, чтобы отправить сигнал в родителя. waitpid () тогда установит errno на EINTR и возврат. В этой точке Вы проверяете на waitpid возвращаемое значение и errno, замечаете, что были отправлены сигнал и принимаете соответствующие меры.

1
ответ дан Krunch 26 November 2019 в 19:33
поделиться