Linux多线程编程学习代码(代码已上传gitee,还请各位兄弟点个Star哦!)
https://gitee.com/chenshao777/linux_thread.git
笔记:
1.线程信号处理:
int sigaction(int signum,
const struct sigaction *act,
struct sigaction *oldact);
函数功能:给signum信号设置一个处理函数,处理函数在struct sigaction中指定
act.sa_mask 信号屏蔽字(信号掩码)
act.sa_handler 信号集处理程序
2.信号集操作函数
// 清空信号集
int sigemptyset(sigset_t *set);
// 将所有信号加入信号集
int sigfillset(sigset_t *set);
// 增加一个信号到信号集
int sigaddset(sigset_t *set, int signum);
// 删除信号集中的一个信号
int sigdelset(sigset_t *set, int signum);
3.多线程信号屏蔽处理
int pthread_sigmask(int how,
const sigset_t *set,
sigset_t *oldset);
how = SIG_BLOCK: 向当前的信号掩码中添加set,其中set表示要阻塞的信号组
SIG_UNBLOCK: 向当前的信号掩码中删除set,其中set表示要取消阻塞的信号组
SIG_SETMASK: 将当前的信号掩码替换为set,其中set表示新的信号掩码
**PS:**在多线程中,新线程的当前信号掩码会继承创造它的线程的信号掩码
一般情况下,被阻塞的信号将不能中断此线程的执行,除非此信号的产生是因为程序运行出错,如SIGSEGC;
另外信号SIGKILL和SIGSTOP无法被阻塞。
spu.h文件
#ifndef _SPU_H_
#define _SPU_H_
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<signal.h>
#include<errno.h>
#endif
06.thread_mask.c文件
/*
1.创建2个线程
2.线程1调用 pthread_sigmask 屏蔽 SIGQUIT 信号,延时,等待线程2先执行完,使线程1最后执行 sigaction
3.线程2不屏蔽 SIGQUIT 信号
4.线程1屏蔽了 SIGQUIT 信号,但是信号处理函数仍热执行了
5.发现 sigaction 函数以最后调用的线程为准
*/
#include "spu.h"
void sig_handler1()
{
printf("this is handler01\n");
}
void sig_handler2()
{
printf("this is handler02\n");
}
void *thread_fun1(void *arg)
{
sleep(1); // 延时,等待线程2先执行完,使线程1最后执行 sigaction
printf("I am thread01\n");
struct sigaction act;
memset(&act, 0, sizeof(act));
// 添加SIGQUIT信号到信号集
sigaddset(&act.sa_mask, SIGQUIT);
// 设置信号处理函数
act.sa_handler = sig_handler1;
// 设置线程信号处理
sigaction(SIGQUIT, &act, NULL);
// 屏蔽信号
pthread_sigmask(SIG_BLOCK, &act.sa_mask, NULL);
sleep(3);
return (void*)1;
}
void *thread_fun2(void *arg)
{
printf("I am thread02\n");
struct sigaction act;
memset(&act, 0, sizeof(act));
// 添加SIGQUIT信号到信号集
sigaddset(&act.sa_mask, SIGQUIT);
// 设置信号处理函数
act.sa_handler = sig_handler2;
// 设置线程信号处理
sigaction(SIGQUIT, &act, NULL);
// 屏蔽信号
//pthread_sigmask(SIG_BLOCK, &act.sa_mask, NULL);
sleep(3);
return (void*)2;
}
int main()
{
int err1,err2;
pthread_t tid1, tid2;
void *__retval;
err1 = pthread_create(&tid1, NULL, thread_fun1, NULL);
if(err1 != 0)
{
printf("thread1 create failed\n");
return 0;
}
err2 = pthread_create(&tid2, NULL, thread_fun2, NULL);
if(err2 != 0)
{
printf("thread2 create failed\n");
return 0;
}
sleep(2);
// 向线程1发送SIGQUIT信号
pthread_kill(tid1, SIGQUIT);
// 向线程2发送SIGQUIT信号
pthread_kill(tid2, SIGQUIT);
// 链接线程1
printf("pthread_join1 return %d\n",pthread_join(tid1, NULL));
// 链接线程2
printf("pthread_join2 return %d\n",pthread_join(tid2, NULL));
pthread_exit(__retval);
}
06.thread_signal.c文件
/*
1.创建一个线程
2.1 sleep(1)后,向线程发送一个信号0,此时发送信号失败
2.2 线程中先sleep(1),main中发送一个SIGQUIT信号,直接退出整个进程,没有任何打印信息
*/
#include "spu.h"
void *thread_fun1(void *arg)
{
sleep(1);
printf("I am thread 1\n");
return (void*)0;
}
int main(int argc, char *argv[])
{
int err1;
pthread_t thread_id1;
int s;
void *__retval;
err1 = pthread_create(&thread_id1, NULL, thread_fun1, NULL);
if(err1 != 0)
printf("create failed!\n");
else
printf("create success!\n");
s = pthread_kill(thread_id1, SIGQUIT); //由于线程没有作任何信号处理,退出整个进程
//由于线程退出,所以找不到线程
if(s == ESRCH)
printf("thread is not found\n");
pthread_exit(__retval);
}