我上面的代码用于调试不同线程的信号屏蔽时发生的情况。我在这段代码中看到的是,被USR2屏蔽的第一个线程使整个过程终止。
如果能有人帮助我为什么会发生这种情况以及如何使用pthread_sigmask处理不同线程中的不同信号,那将是非常棒的。
我试图从具有某些信号掩码的main函数创建一个线程,然后从当前线程中创建了一个新线程,并删除了一些信号掩码。即使我尝试为新线程添加额外的信号掩码,程序仍然会终止。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
/* Simple error handling functions */
#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
static void *
sig_thread_1(void *arg)
{
sigset_t *set = arg;
int s, sig;
printf("%p created\n",pthread_self() );
printf("after new set %s SIGUSR1\n",sigismember(set,SIGUSR1)==0?"is not":"is" );
printf("after new set %s SIGUSR2\n",sigismember(set,SIGUSR2)==0?"is not":"is" );
printf("after new set %s SIGRTMIN\n",sigismember(set,SIGRTMIN)==0?"is not":"is" );
printf("after new set %s SIGQUIT\n",sigismember(set,SIGQUIT)==0?"is not":"is" );
for (;;) {
s = sigwait(set, &sig);
if (s != 0)
handle_error_en(s, "sigwait");
printf("Signal handling %lu thread got signal %d\n",pthread_self(), sig);
}
}
static void *
sig_thread(void *arg)
{
sigset_t *set = arg;
int s, sig;
sigset_t set1=*set;
pthread_t thread1;
// sigemptyset(&set1);
sigdelset(&set1, SIGQUIT);
sigdelset(&set1, SIGUSR1);
printf("%p created\n",pthread_self() );
printf("after old set %s SIGUSR1\n",sigismember(set,SIGUSR1)==0?"is not":"is" );
printf("after old set %s SIGUSR2\n",sigismember(set,SIGUSR2)==0?"is not":"is" );
printf("after old set %s SIGRTMIN\n",sigismember(set,SIGRTMIN)==0?"is not":"is" );
printf("after old set %s SIGQUIT\n",sigismember(set,SIGQUIT)==0?"is not":"is" );
s = pthread_sigmask(SIG_UNBLOCK, &set1, NULL);
if (s != 0)
handle_error_en(s, "pthread_sigmask");
s = pthread_create(&thread1, NULL, &sig_thread_1, (void *) &set1);
if (s != 0)
handle_error_en(s, "pthread_create fail");
printf("after old set1 %s SIGUSR1\n",sigismember(&set1,SIGUSR1)==0?"is not":"is" );
printf("after old set1 %s SIGUSR2\n",sigismember(&set1,SIGUSR2)==0?"is not":"is" );
printf("after old set1 %s SIGRTMIN\n",sigismember(&set1,SIGRTMIN)==0?"is not":"is" );
printf("after old set1 %s SIGQUIT\n",sigismember(&set1,SIGQUIT)==0?"is not":"is" );
// return;
for (;;) {
printf("after old set %s SIGUSR1\n",sigismember(set,SIGUSR1)==0?"is not":"is" );
printf("after old set %s SIGUSR2\n",sigismember(set,SIGUSR2)==0?"is not":"is" );
printf("after old set %s SIGRTMIN\n",sigismember(set,SIGRTMIN)==0?"is not":"is" );
printf("after old set %s SIGQUIT\n",sigismember(set,SIGQUIT)==0?"is not":"is" );
s = sigwait(set, &sig);
if (s != 0)
handle_error_en(s, "sigwait");
printf("Signal handling %lu thread got signal %d\n",pthread_self(), sig);
}
}
int
main(int argc, char *argv[])
{
pthread_t thread;
pthread_t thread1;
sigset_t set;
int s;
/* Block SIGQUIT and SIGUSR1; other threads created by main()
will inherit a copy of the signal mask. */
sigemptyset(&set);
sigaddset(&set, SIGQUIT);
sigaddset(&set, SIGUSR1);
sigaddset(&set, SIGUSR2);
sigaddset(&set, SIGRTMIN);
s = pthread_sigmask(SIG_BLOCK, &set, NULL);
if (s != 0)
handle_error_en(s, "pthread_sigmask");
s = pthread_create(&thread, NULL, &sig_thread, (void *) &set);
if (s != 0)
handle_error_en(s, "pthread_create fail");
/* Main thread carries on to create other threads and/or do
other work */
pause(); /* Dummy pause so we can test program */
}