Linux-c,Signal相关

Linux-c,Signal相关

代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
  
void *thread_func(void *arg){
    
    

        printf("I am new thread\n");
        return (void *)0;

}


int main(){
    
    


        pthread_t tid;
        int err, s;

        err = pthread_create(&tid, NULL, thread_func, NULL);

        if(err){
    
    
                printf("create new thread failed \n");
                return 1;
        }

        sleep(2);

        s = pthread_kill(tid, 0);

        if(s == ESRCH){
    
    
                printf("new thread tid is not found\n");
        }

        return 

ERR:

thread_kill.c:32:10: error: ‘ESRCH’ undeclared (first use in this function)

信号

进程信号处理:
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

给信号signum设置一个处理函数,处理函数在sigaction中指定

act.sa_mask 信号屏蔽字

act.sa_handler信号集处理程序

int sigemptyset(sigset_t *set);清空信号集

int sigfillset(sigset_t *set);将所有信号加入信号集

int sigaddset(sigset_t *set, int signum);增加一个信号到信号集

int sigdelset(sigset_t *set, int signum);删除一个信号到信号集

多线程信号屏蔽处理

int sigprocmaskfint how,const sigset_t *set, sigset_t oldset)/

int pthread_sigmask(int how, coist sigset_t "set, sigset_t "oldset);

how = SIG_BLOCK:向当前的信号掩码中添加set,其中set表示要阻塞的信号组。

SIG_UNBLOCK:向当前的信号掩码中删除set,其中set表示要取消阻塞的信号组。

SIG_SETMASK:将当前的信号掩码替换为set,其中set表示新的信号掩码。

在多线程中,新线程的当前信号掩码会继承创造它的那个线程的信号掩码

模模糊糊的跟着敲了堆代码,慢慢搞吧

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

void sig_handler1(int arg){
    
    

        printf("thread 1 get signal\n");
        return ;

}

void sig_handler2(int arg){
    
    

        printf("thread 2 get signal \n");
        return ;

}


void *thread_func1(void *arg){
    
    

        printf("I am new thread 1 \n");

        struct sigaction act;
        memset(&act, 0, sizeof(act));

        sigaddset(&act.sa_mask, SIGQUIT);
        act.sa_handler = sig_handler1;
        sigaction(SIGQUIT, &act, NULL);

        pthread_sigmask(SIG_BLOCK, &act.sa_mask, NULL);
        sleep(2);



}

void *thread_func2(void *arg){
    
    

        printf("I am new thread 2 \n");

        struct sigaction act;
        memset(&act, 0, sizeof(act));

        sigaddset(&act.sa_mask, SIGQUIT);
        act.sa_handler = sig_handler2;
        sigaction(SIGQUIT, &act, NULL);

        //pthread_sigmask(SIG_BLOCK, &act.sa_mask, NULL);
        sleep(2);

}

int main(){
    
    

        pthread_t tid1, tid2;
        int err, s;

        err = pthread_create(&tid1, NULL, thread_func1, NULL);
        if(err){
    
    

                printf("create new thread 1 failed\n");
                return ;
        }


        err = pthread_create(&tid2, NULL, thread_func2, NULL);
        if(err){
    
    

                printf("create new thread 2 failed\n");
                return ;
        }

        sleep(1);

        s = pthread_kill(tid1, SIGQUIT);
        if(s){
    
    

                printf("send signal to thread 1 failed \n");
        }


        s = pthread_kill(tid2, SIGQUIT);
        if(s){
    
    

                printf("send signal to thread 2 failed \n");
        }

        pthread_join(tid1, NULL);
        pthread_join(tid2, NULL);


        return 0;
}

注册/销毁清理函数

线程可以安排它退出时的清理操作,这与进程的可以用atexit函数安排进程退出时需要调用的函颓类似。这样的函数称为线程清理处理程序。线程可以建立多个清理处理程序,处理程序记录在栈中,所以这些处理程序执行的顺序与他们注册的顺序相反

pthread_cleanup_push (void (rtn)(void) . void *args)#注册处理程序

pthread_cleanup_pop ( int excute) #清除处理程序

这两个函数要成对的出现,否则编译无法通过

当执行以下操作时调用清理函数,清理函数的参数由args传入

1、调用pthread_exit

2、响应取消请求(请你来验证)

3、用非零参数调用pthread_cleanup_pop

代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>


void *first_clean(void *arg){
    
    

        printf("%s is first clean \n", arg);
        return (void *)0;

}

void *second_clean(void *arg){
    
    

        printf("%s is second clean \n", arg);
        return (void *)0;

}

void *thread_func1(void *arg){
    
    

        printf("I am thread 1 \n");

        pthread_cleanup_push(first_clean, "thread1");
        pthread_cleanup_push(second_clean, "thread1");

        pthread_cleanup_pop(1);
        pthread_cleanup_pop(0);

        return (void *)1;

}

void *thread_func2(void *arg){
    
    

        printf("I am thread 2\n" );

        pthread_cleanup_push(first_clean, "thread2");
        pthread_cleanup_push(second_clean, "thread2");

        pthread_cleanup_pop(0);
        pthread_cleanup_pop(0);

        pthread_exit((void *) 2);

}


int main(){
    
    


        pthread_t tid1, tid2;
        int err;

        err = pthread_create(&tid1, NULL, thread_func1, NULL);
        if(err){
    
    
                printf("create new thread 1 failed \n");
                return ;
        }

        err = pthread_create(&tid2, NULL, thread_func2, NULL);
        if(err){
    
    
                printf("create new thread 2 failed \n");
                return ;
        }

        sleep(2);


        return 0;
}

运行结果

I am thread 1 
thread1 is second clean 
I am thread 2

猜你喜欢

转载自blog.csdn.net/qq_44861043/article/details/119605499