#define _GNU_SOURCE 1 #include #include #include #include #include #include #define sys(code) if ((code) < 0) { perror(#code); exit(1); } pthread_t mainThread; pthread_t childThread; void handler(int signo, siginfo_t* siginfo, void* context) { if (pthread_equal(pthread_self(), mainThread)) { printf("received signal in main thread (WRONG)\n"); } else if (pthread_equal(pthread_self(), childThread)) { printf("received signal in child thread (CORRECT)\n"); } else { printf("received signal in other thread (?)\n"); } } void* threadMain(void* param) { // Give main thread time to send us SIGUSR1. usleep(100000); // Check what signals are pending with sigpending(). sigset_t pending; sys(sigpending(&pending)); if (sigismember(&pending, SIGUSR1)) { printf("sigpending() says signal is pending in child thread (CORRECT)\n"); } else { printf("sigpending() says signal is NOT pending in child thread (WRONG)\n"); } // Unblock SIGUSR1 to see if it gets delivered. sigset_t mask; sys(sigemptyset(&mask)); sys(sigaddset(&mask, SIGUSR1)); sys(sigprocmask(SIG_UNBLOCK, &mask, NULL)); return NULL; } int main() { // Register a signal handler for SIGUSR1. struct sigaction action; memset(&action, 0, sizeof(action)); action.sa_sigaction = &handler; action.sa_flags = SA_SIGINFO; sys(sigaction(SIGUSR1, &action, NULL)); // Block SIGUSR1. sigset_t mask; sys(sigemptyset(&mask)); sys(sigaddset(&mask, SIGUSR1)); sys(sigprocmask(SIG_BLOCK, &mask, NULL)); // Start child thread. mainThread = pthread_self(); if (pthread_create(&childThread, NULL, &threadMain, NULL) < 0) { fprintf(stderr, "pthread_create failed\n"); exit(1); } // Send SIGUSR1 to child thread. printf("sending signal to child thread with pthread_kill()...\n"); if (pthread_kill(childThread, SIGUSR1) < 0) { fprintf(stderr, "pthread_kill failed\n"); exit(1); } // Check if sigpending() returns SIGUSR1. sigset_t pending; sys(sigpending(&pending)); if (sigismember(&pending, SIGUSR1)) { printf("sigpending() says signal is pending in main thread (WRONG)\n"); } else { printf("sigpending() says signal is NOT pending in main thread (CORRECT)\n"); } // Unblock SIGUSR1 to see if it gets delivered to this thread. sys(sigemptyset(&mask)); sys(sigaddset(&mask, SIGUSR1)); sys(sigprocmask(SIG_UNBLOCK, &mask, NULL)); pthread_join(childThread, NULL); }