Как родительский процесс проверяет отправленный сигнал дочерним процессом - PullRequest
1 голос
/ 19 июля 2011

На основании этого http://man7.org/tlpi/code/online/dist/procexec/fork_sig_sync.c.html

/* fork_sig_sync.c

   Demonstrate how signals can be used to synchronize the actions
   of a parent and child process.
*/
#include <signal.h>
#include "curr_time.h"                  /* Declaration of currTime() */
#include "tlpi_hdr.h"

#define SYNC_SIG SIGUSR1                /* Synchronization signal */

static void             /* Signal handler - does nothing but return */
handler(int sig)
{
}

int
main(int argc, char *argv[])
{
    pid_t childPid;
    sigset_t blockMask, origMask, emptyMask;
    struct sigaction sa;

    setbuf(stdout, NULL);               /* Disable buffering of stdout */

    sigemptyset(&blockMask);
    sigaddset(&blockMask, SYNC_SIG);    /* Block signal */
    if (sigprocmask(SIG_BLOCK, &blockMask, &origMask) == -1)
        errExit("sigprocmask");

    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    sa.sa_handler = handler;
    if (sigaction(SYNC_SIG, &sa, NULL) == -1)
        errExit("sigaction");

    switch (childPid = fork()) {
    case -1:
        errExit("fork");

    case 0: /* Child */

        /* Child does some required action here... */

        printf("[%s %ld] Child started - doing some work\n",
                currTime("%T"), (long) getpid());
        sleep(2);               /* Simulate time spent doing some work */

        /* And then signals parent that it's done */

        printf("[%s %ld] Child about to signal parent\n",
                currTime("%T"), (long) getpid());
        if (kill(getppid(), SYNC_SIG) == -1)
            errExit("kill");

        /* Now child can do other things... */

        _exit(EXIT_SUCCESS);

    default: /* Parent */

        /* Parent may do some work here, and then waits for child to
           complete the required action */

        printf("[%s %ld] Parent about to wait for signal\n",
                currTime("%T"), (long) getpid());
        sigemptyset(&emptyMask);
        if (sigsuspend(&emptyMask) == -1 && errno != EINTR)  // <<<<< Question
            errExit("sigsuspend");
        printf("[%s %ld] Parent got signal\n", currTime("%T"), (long) getpid());

        /* If required, return signal mask to its original state */

        if (sigprocmask(SIG_SETMASK, &origMask, NULL) == -1)
            errExit("sigprocmask");

        /* Parent carries on to do other things... */

        exit(EXIT_SUCCESS);
    }
}

Вопрос

Когда родительский процесс вызывает sigsuspend , почему он не проверяет, является ли отправленный сигнал SYNC_SIG?

http://pubs.opengroup.org/onlinepubs/7908799/xsh/sigsuspend.html

1 Ответ

0 голосов
/ 19 июля 2011

Код предполагает, что никакой другой сигнал не возникнет во время работы программы, поэтому он не беспокоится о том, что он получил правильный. Это означает, что при возникновении любого другого сигнала программа может завершиться ошибкой.

добавить

Есть несколько способов проверить, что правильный сигнал отправлен. Вы можете настроить обработчик на sig_atomic_t global var и проверить, что его набор после sigsuspend возвращает (цикл, чтобы повторить вызов sigsuspend, если это не так). Или вы можете установить маску, переданную sigsuspend, чтобы заблокировать все, КРОМЕ SYNC_SIG. Ни один из них не будет работать, если какой-то другой процесс отправит поддельный SIGUSR1 вашему процессу, но это произойдет, только если кто-то намеренно пытается саботировать вашу программу.

...