Home > Net >  Using a signal listener thread - how do I stop it?
Using a signal listener thread - how do I stop it?

Time:09-17

A snippet from my main method:

  std::atomic_bool runflag;
  // ...
  std::thread signaller([&]() mutable {
    while (runflag) {
      int sig;
      int rcode = sigwait(&set, &sig);
      if (rcode == 0) {
        switch (sig) {
          case SIGINT: {
            // handle ^C
          }
        }
      }
    }
  });
  
  while (runflag) {
    next = cin.get();
    // handle character input
  }
  signaller.join();

I'm using the sigwait()-based approach for detecting SIGINT sent from the command line.

The signaller thread uses sigwait() to listen for signals. The program terminates when runflag is set false. However, the signaller thread will still be blocked at sigwait when this happens. I don't think I can use condition variables, as sigwait has no way to hook into one. Is there an alternative solution that is preferably not Linux-only?

EDIT 1: Alternatively, is there an interruptible version of sigwait?

CodePudding user response:

You can use the sigtimedwait() function, which returns after a timeout given as a parameter.

You will need to check the return value from sigtimedwait() to check if it finished because of timeout or the signal arrived and then depending on this value you will need to handle signal or just check runflag and run again sigtimedwait().

Here is more about it from another answer: https://stackoverflow.com/a/58834251/11424134

CodePudding user response:

You can wake up the signal-handling thread by having the process send another signal to itself, eg.

kill(getpid(), SIGUSR1);
  • Related