多线程信号处理

时间:2019-07-24 04:42:44

标签: c linux

我上面的代码用于调试不同线程的信号屏蔽时发生的情况。我在这段代码中看到的是,被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 */
}

0 个答案:

没有答案