学习分享
- 1、信号的基本概念
- 2、查看信号列表
- 3、常见信号名称
- 4、signal库函数
- 5、发送信号kill
- 6、kill - signal (无参信号)示例
- 6.1、kill - signal (不可靠信号)示例
- 6.2、kill - signal (可靠信号)示例
- 7、信号分类
- 7.1、信号运行原理分类
- 7.2、信号是否携带数据分类
- 8、sigaction库函数
- 9、sigqueue库函数
- 10、sigaction - sigqueue(带参信号)示例
- 11、屏蔽信号
- 11.1、信号集操作函数
- 11.2、sigprocmask函数
- 11.3、屏蔽信号示例
1、信号的基本概念
信号是UNIX系统响应某些状况而产生的事件,进程在接收到信号时会采取相应的行动。
信号是因为某些错误条件而产生的,比如内存段冲突、浮点处理器错误或者非法指令等
它们由shell和终端管理器产生以引起中断。
进程可以生成信号、捕捉并响应信号或屏蔽信号
2、查看信号列表
使用命令:kill -l 查看信号列表
CTRL+C 就是向进程发送2号信号
- 1-31为系统信号
- 34-64为扩展信号,提供开发人员使用
3、常见信号名称
信号的名称是在头文件 signal.h里定义的
- SIGUSR1 和SIGUSR2没有任何含义,由开发人员自由定义
4、signal库函数
类型QT中的connect
5、发送信号kill
类似QT中的emit
6、kill - signal (无参信号)示例
#include <iostream>
#include <unistd.h>
#include <signal.h>
using namespace std;void signal_function(int num)/信号处理函数
{cout<<"pid = "<<getpid()<<"信号处理函数被触发"<<endl;
}
int main()
{//信号的注册绑定signal(SIGUSR1,signal_funcion);pid_t pid =fork();if(pid>0){//父进程sleep(5);//发送信号kill(pid,SIGUSR1);while(1){}}else {//子进程while(1){cout<<"子进程pid = "<<getpid()<<endl;sleep(1);}}return 0;
}
6.1、kill - signal (不可靠信号)示例
1-31为不可靠信号,连续发送多次,响应1次。不会连续触发处理函数调用,但是间隔发送就会挨个处理。带有操作系统分配的特殊含义
#include <iostream>
#include <unistd.h>
#include <signal.h>
using namespace std;void signal_function(int num)/信号处理函数
{cout<<"pid = "<<getpid()<<"信号处理函数被触发"<<endl;
}
int main()
{//信号的注册绑定signal(SIGUSR1,signal_funcion);pid_t pid =fork();if(pid>0){//父进程sleep(5);for(int i=0;i<3;i++){cout<<"i = "<<i<<endl; //发送信号kill(pid,SIGUSR1);sleep(1);}while(1){}}else {//子进程while(1){cout<<"子进程pid = "<<getpid()<<endl;sleep(1);}}return 0;
}
6.2、kill - signal (可靠信号)示例
34-64为可靠信号,连续发送会连续触发处理函数调用
#include <iostream>
#include <unistd.h>
#include <signal.h>
using namespace std;void signal_function(int num)/信号处理函数
{cout<<"pid = "<<getpid()<<"信号处理函数被触发"<<endl;
}
int main()
{//信号的注册绑定signal(SIGUSR1,signal_funcion);pid_t pid =fork();if(pid>0){//父进程sleep(5);for(int i=0;i<3;i++){cout<<"i = "<<i<<endl; //发送信号kill(pid,SIGRTMIN);}while(1){}}else {//子进程while(1){cout<<"子进程pid = "<<getpid()<<endl;sleep(1);}}return 0;
}
7、信号分类
7.1、信号运行原理分类
- 1-31不可靠信号:连续发送不会连续触发处理函数调用,但是间隔发送就会挨个处理,带有操作系统分配的特殊含义
- 34-64可靠信号:连续发送会连续触发处理函数调用
7.2、信号是否携带数据分类
1、无参信号:signal - kill
2、携带参数信号 :sigaction - sigqueue
8、sigaction库函数
Linux中查看函数详情命令:man sigaction
9、sigqueue库函数
Linux中查看函数详情命令:man sigqueue
10、sigaction - sigqueue(带参信号)示例
#include <iostream>
#include <unistd.h>
#include <signal.h>
using namespace std;void sigaction_fuction(int num,siginfo_t* info, void*vo) //num指信号编号
{int res= info->si_int;cout<<"pid = "<<getpid()<<"信号处理函数被触发 res="<<res<<endl;
}
int main()
{struct sigaction act;act.sa_sigaction =sigaction_function://带参信号处理函数act.sa_flags = SA_SIGINFO;//当前信号带参数sigction(SIGUSR1,&act,NULL);//带参信号的绑定pid_t pid =fork();if(pid>0){//父进程sleep(5);//带参信号发送union sigval val;//联合体val.sival_int =1001;sigqueue(pid,SIGUSR1,val);while(1){}}else {//子进程while(1){cout<<"子进程pid = "<<getpid()<<endl;sleep(1);}}return 0;
}
11、屏蔽信号
11.1、信号集操作函数
11.2、sigprocmask函数
11.3、屏蔽信号示例
#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
using namespace std;
void sigaction_fuction(int num,siginfo_t* info, void*vo) //num指信号编号
{int res= info->si_int;cout<<"pid = "<<getpid()<<"信号处理函数被触发 res="<<res<<endl;
}
int main()
{struct sigaction act;act.sa_sigaction =sigaction_function://带参信号处理函数act.sa_flags = SA_SIGINFO;//当前信号带参数sigction(SIGUSR1,&act,NULL);//带参信号的绑定pid_t pid =fork();if(pid>0){//父进程sleep(5);//带参信号发送union sigval val;//联合体val.sival_int =1001;sigqueue(pid,SIGUSR1,val);while(1){}}else {//子进程//屏蔽信号//创建信号集sigset_t array;//初始化信号集sigemptyset(&array);//添加需要屏蔽的信号sigaddset(&array,SIGUSR1);sigaddset(&array,SIGUSR2);//启用信号“黑名单”if(sigprocmask(SIG_BLOCK,&array,NULL)<0){perror("sigprocmask error");}while(1){cout<<"子进程pid = "<<getpid()<<endl;sleep(1);}}return 0;
}