The signal is pending when it is delivered to the OS, but the process or thread blocked it. If you did not block SIGUSR1, then it will be delivered, and the default location of SIGUSR1 is to terminate the process. Your sigpending does nothing in this scenario; it is effectively circumvented. Any SIGUSR1 block first with pthread_sigmask or (optionally) processes it.
All this is dubious design. With blocked / sigpending code, depending on how long SECONDS is configured for you, you can still wait a long time until the stream closes to find that it is time to shut down. If you really want to use signals for this, I would suggest installing a signal handler that sets the switch. When SIGUSR1 is delivered, the handler will be called, it will set the switch, sleep will be interrupted by a signal, you will check the EINTR and immediately bypass the loop to check the switch, and then pthread_exit .
Option 1 (compiled on Linux)
#define _POSIX_C_SOURCE 2 #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <time.h> #include <signal.h> void* foo(void* arg) { sigset_t set, isSignal, allSigs; sigfillset(&allSigs); if (sigprocmask(SIG_SETMASK, &allSigs, NULL) == -1) { printf("sigprocmask: %m\n"); exit(1); } sigemptyset(&set); if (sigaddset(&set, SIGUSR1) == -1) { printf("sigaddset: %m\n"); exit(1); } while (1) { if (sigpending(&isSignal) != 0) { printf("sigpending: %m\n"); exit(1); } else if (sigismember(&isSignal, SIGUSR1)) { printf("signal pending for thread, exiting\n"); break; } printf("Doing groovy thread stuff...\n"); sleep(2); } return NULL; } int main(int argc, char *argv[]) { pthread_t tid; int rc; rc = pthread_create(&tid, NULL, foo, NULL); if (rc) { printf("pthread_create: %m\n"); exit(1); } sleep(10); pthread_kill(tid, SIGUSR1); pthread_join(tid, NULL); }
Option 2 (compiled on Linux)
#define _POSIX_C_SOURCE 2 #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <time.h> #include <signal.h> volatile int stop = 0; void handler(int sig) { stop = 1; } void* foo(void* arg) { signal(SIGUSR1, handler); //use sigaction, i'm too lazy here while (! stop) { printf("Doing groovy thread stuff...\n"); if (sleep(4) > 0) if (errno == EINTR) { printf("sleep interrupted, exiting thread...\n"); continue; } } return NULL; } int main(int argc, char *argv[]) { pthread_t tid; int rc; rc = pthread_create(&tid, NULL, foo, NULL); if (rc) { printf("pthread_create: %m\n"); exit(1); } sleep(10); pthread_kill(tid, SIGUSR1); pthread_join(tid, NULL); }
Option 3 Use a different mechanism if you can. Advised.