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