线程与信号 -- pthread_sigmask() sigwait()

一、主线程发送USR1信号给子线程1  ,子线程中添加 信号捕捉,子线程2没有捕捉信号,导致直接退出

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>

#define handle_error_en(en, msg) \
    do {errno = en; perror(msg); exit(EXIT_FAILURE); }while(0)


static void *sig_thread1(void *arg)
{
    sigset_t *set = (sigset_t *)arg;
    int ret, sig;

    sigaddset(set, SIGUSR1);
    pthread_sigmask(SIG_SETMASK, set, NULL);
    for (;;)
    {
        // 等待被屏蔽的信号 SIGQUIT
        printf("before sigwait1..\n");
        ret = sigwait(set, &sig);
        if (ret != 0)
            handle_error_en(ret, "thread2 sigwait");
   
        printf("Signal handling thread1 got signal %d\n", sig);
    }
}       
    
static void *sig_thread2(void *arg)
{
    sigset_t set;
    sigemptyset(&set);
    
    int ret, sig;
    
    for (;;) 
    {
        // thread2 没有设置捕捉任何信号,
        // 除SIGQUIT被屏蔽,其余信号均可导致线程退出
        printf("before sigwait2..\n");  
        ret = sigwait(&set, &sig);      
        if (ret != 0)                   
            handle_error_en(ret, "thread2 sigwait");
                                        
        printf("Signal handling thread2 got signal %d\n", sig);
    }                                   
}   
int main(int argc, const char *argv[])  
{
    pthread_t thread1;
    pthread_t thread2;
    sigset_t set;
    int ret; 
    
    sigemptyset(&set);
    sigaddset(&set, SIGQUIT);
    
    // SIG_BLOCK 屏蔽  SIG_UNBLOCK 解屏蔽  SIG_SETMASK 设置
    ret = pthread_sigmask(SIG_BLOCK, &set, NULL);
    if (ret!=0 )
        handle_error_en(ret, "pthread_sigmask");

    ret = pthread_create(&thread1, NULL, sig_thread1, &set);


    ret = pthread_create(&thread2, NULL, sig_thread2, NULL);

    sleep(2);
    pthread_kill(thread1, SIGUSR1);
    printf("kill thread1 SIGUSR1.\n");

    sleep(2);
    pthread_kill(thread2, SIGUSR1);
    printf("kill thread2 SIGUSR1.\n");

    pause();

    return 0;
}

二、 线程1 捕捉被屏蔽信号,线程2没有捕捉

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>

#define handle_error_en(en, msg) \
    do {errno = en; perror(msg); exit(EXIT_FAILURE); }while(0)


static void *sig_thread1(void *arg)
{
    sigset_t *set = (sigset_t *)arg;
    int ret, sig;

    for (;;)
    {
        // 等待被屏蔽的信号 SIGQUIT
        printf("before sigwait1..\n");
        ret = sigwait(set, &sig);
        if (ret != 0)
            handle_error_en(ret, "thread2 sigwait");
        
        printf("Signal handling thread1 got signal %d\n", sig);
    }
}       
    
static void *sig_thread2(void *arg)
{
    sigset_t set;
    sigemptyset(&set);
    
    int ret, sig;
    
    for (;;) 
    {
        // thread2 没有设置捕捉任何信号,
        // 除SIGQUIT被屏蔽,其余信号均可导致线程退出
        printf("before sigwait2..\n");  
        ret = sigwait(&set, &sig);      
        if (ret != 0)                   
            handle_error_en(ret, "thread2 sigwait");
                                        
        printf("Signal handling thread2 got signal %d\n", sig);
    }                                   
}   
int main(int argc, const char *argv[])  
{
    pthread_t thread1;
    pthread_t thread2;
    sigset_t set;
    int ret; 
    
    sigemptyset(&set);
    sigaddset(&set, SIGQUIT);
    
    // SIG_BLOCK 屏蔽  SIG_UNBLOCK 解屏蔽  SIG_SETMASK 设置
    ret = pthread_sigmask(SIG_BLOCK, &set, NULL);
    if (ret!=0 )
        handle_error_en(ret, "pthread_sigmask");

    ret = pthread_create(&thread1, NULL, sig_thread1, &set);


    ret = pthread_create(&thread2, NULL, sig_thread2, NULL);

    sleep(2);
    pthread_kill(thread1, SIGQUIT);
    printf("kill thread1 SIGQUIT.\n");

    sleep(2);
    pthread_kill(thread2, SIGQUIT);
    printf("kill thread2 SIGQUIT.\n");

    pause();

    return 0;
}

猜你喜欢

转载自blog.csdn.net/centnetHY/article/details/82494345
今日推荐