1

I am trying to set up SIGINT signal handler to wake up the main thread via binary semaphore. For that, as I attach below, I set up a SIGINT handler to run handler() function which just increments semaphore. Meanwhile, in the main thread just sem_wait(&mutex) is called in the infinite loop and then it just gets the semaphore value and prints it.

The way of waiting for a semaphore I did is while (sem_wait(&mutex)); because apparently every time Ctrl+C is pressed the sem_wait() returns with EINTR error. I did not expect it to be that way as I thought it behaves as true passive waiting with suspension of the process.

I feel that using sem_post() from inside signal handlers should be fine as that is a async-signal-safe function. But shouldn't there be more elegant design choices to do what I want to do? i.e. put a thread to passive wait and then wake it up from the signal handler. I would be grateful for any advice.

The code:

sem_t mutex;

static void handler (int num) {
    sem_post(&mutex);
}
 
int main() {
    struct sigaction sa;

    sa.sa_handler = handler;
    sa.sa_flags = 0;
    if (sigemptyset(&sa.sa_mask) == -1) {
        perror("sigemptyset failed");
        return EXIT_FAILURE;
    }

    if (sigaction(SIGINT, &sa, NULL) == -1) {
        perror("sigaction failed");
        return EXIT_FAILURE;
    }

    sem_init(&mutex, 0, 0);

    int sval;

    printf ("Get ready, press Ctrl+C...\n");

    while (1) {
        while (sem_wait(&mutex))
            printf ("%s\n", strerror(errno));

        sem_getvalue(&mutex, &sval);
        printf("sem is %d\n", sval);
    }

    printf("Bye");
}
7
  • Take a look here on how to wait for a signal: stackoverflow.com/questions/58427667/… Commented Feb 5 at 16:43
  • Do you insist that the paused thread be awakened by action of a signal handler, or would it be sufficient for it to be awakened as a result of the program receiving a signal? These are not the same thing. Commented Feb 5 at 16:52
  • You could set sa.sa_flags = SA_RESTART;. Commented Feb 5 at 16:59
  • … I don't think sem_wait is restartable on catching a signal though, so the SA_RESTART flag probably won't work. Commented Feb 5 at 17:20
  • @IanAbbott, some versions of the Linux docs for sem_wait() note explicitly that it is always interrupted by a signal handler, regardless of SA_RESTART, so you're right in at least that sense. I'm having trouble finding any more general documentation of that property, but that doesn't mean it does not apply widely. Commented Feb 5 at 17:29

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.