学习分享
- 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;
}


















