目录
前言
一、信号是什么?
二、信号要素
1.信号的名称
2.进程对信号的响应
三、信号相关函数
总结
Linux系统下的信号与再win下学习stm32的中断有些相似,此文是学习完了stm32后学习Linux操作系统下的信号的一些小笔记
1.信号是UNIX系统响应某些状况而产生的事件,进程在接收到信号时会采取相应的行动。
2.信号是因为某些错误条件而产生的,比如内存段冲突、浮点处理器错误或者非法指令等。
3.信号是在软件层次上对中断的一种模拟,所以通常把它称为是软中断。
4.这里给出硬和软中断的区别:
硬件中断(外部中断) 外部中断是指由外部设备通过硬件请求的方式产生的中断,也称为硬件中断
软件中断(内部中断) 内部中断是由CPU运行程序错误或执行内部程序调用引起的一种中断,也称为软件中断。
5.举例:
“中断”就是像从一个事件处理转而处理其他事件,处理完毕后继续处理最开始的事件。“信号\"就是属于这么一种“中断\"。我们在终端上敲\"Ctrl+c\"”,就产生一个中断\",相当于产生一个信号,接着就会处理这么一个“中断任务”(默认的处理方式为中断当前进程)。
2.1.忽略信号:不采取任何操作、有两个信号不能被忽略:SIGKILL和SIGSTOP。
注:SIGKILL和SIGSTOP这两个信号是不会被捕捉、阻塞、忽略的。
2.2.捕获并处理信号:内核中断正在执行的代码,转去执行信号的处理函数。
2.3.执行默认操作:默认操作通常是终止进程,这取决于被发送的信号。
1.signal函数
函数原型:
__sighandler_t signal(int signum, __sighandler_t handler);
返回值:
成功:0
失败:-1
两个参数:
参数1:int signum ->准备捕捉或屏蔽的信号
参数2:__sighandler_t handler ->接收到指定信号时将要调用的函数
注:参数2的函数的参数必须有一个int类型的参数,即接收到的信号代码,它本身的类型是void
handler也可以是下面两个特殊值: SIG_IGN ->屏蔽该信号; SIG_DFL ->恢复默认行为.
例:
#include
#include
#include
#include
void sig_handler(int num)
{
printf("\nrecvive the signal is %d\n", num);
}
int main()
{
int time = 10;
signal(SIGINT, sig_handler);//键盘键入CTRL+C产生信号
printf("enter to the sleep.\n");
//sleep(time);
do{
time = sleep(time);
}while(time > 0);
printf("sleep is over, main over.\n");
exit(0);
}
2.kill函数
作用:给指定进程发送指定信号
格式:kill -signum pid
返回值:
成功:0
失败:-1
3.raise函数
作用:给自己发送信号,raise(sig)等价于kill(getpid(), sig);
返回值:
成功:0
失败:-1
例:
#include
#include
#include
void signal_catchfunc(int);
int main() {
int ret;
signal(SIGINT, signal_catchfunc);
printf("开始生成一个信号\n");
ret = raise(SIGINT);//产生一个信号,成功返回0
if (ret != 0) {
printf("错误,不能生成SIGINT信号\n");
exit(0);//强制退出
}
printf("退出....\n");
return 0;
}
void signal_catchfunc(int signal) {
printf("捕获信号\n");
}
4.pause函数
作用:使进程挂起,直到一个信号被捕获
返回值:-1
例:
//#include
#include // 关于信号的头文件
#include
#include
#include
//using namespace std;
void sighandler1(int signum)
{
printf("捕获信号 %d,跳出...\n", signum);
}
int main()
{
signal(SIGINT,sighandler1);
sleep(2);
printf("before pause\r\n");
pause();//pause使调用者进程挂起,直到一个信号被捕获
printf("after pause\r\n");
}
在程序执行到pause()时,进程挂起,不往下进行,直到有信号进来,才会继续执行
5.sigaction函数
作用:sigaction函数用于改变进程接收到特定信号后的行为。
原型:
int sigaction(int signum,const struct sigaction *act,const struct sigaction *old);
参数:
参数1:信号的值,可以为除SIGKILL及SIGSTOP外的任何一 个特定有效的信号(为这两个信号定义自己的处理函数,将导致信号安装错误)
参数2:指向结构sigaction的一个实例的指针,指定对特定信号的处理,可以为空,进程会以缺省方式对信号处理
参数3:指向的对象用来保存原来对相应信号的处理,可指定oldact为NULL
注:第二个参数尤为重要:
包含了对指定信号的处理、信号所传递的信息、信号处理函数执行过程中应屏蔽掉哪些函数等等
返回值:
成功:0
失败:-1
部分代码示例:
static void sig_usr(int signum)
{
if(signum == SIGUSR1)
{
printf("SIGUSR1 received\n");
}
else if(signum == SIGUSR2)
{
printf("SIGUSR2 received\n");
}
else
{
printf("signal %d received\n", signum);
}
}
/*此处省略多行代码*/
struct sigaction sa_usr;
sa_usr.sa_flags = 0;
sa_usr.sa_handler = sig_usr; //信号处理函数
sigaction(SIGUSR1, &sa_usr, NULL);
sigaction(SIGUSR2, &sa_usr, NULL);
6.setitimer函数:
作用:定时器
原型:
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue));
参数:
参数1:指定定时器类型
ITIMER_REAL:经过指定的时间后,内核将发送SIGALRM信号给本进程
ITIMER_VIRTUAL :程序在用户空间执行指定的时间后,内核将发送SIGVTALRM信号给本进程
ITIMER_PROF :进程在内核空间中执行时,时间计数会减少,通常与ITIMER_VIRTUAL共用,代表进程在用户空间与内核空间中运行指定时间后,内核将发送SIGPROF信号给本进程
返回值:
成功:0
失败:-1
例:
#include
#include
#include
#include
#define COUNT_SEC 1
#define COUNT_USEC 0
#define COUNT_SEC1 3
static void Timer_Test(int sig)
{
printf("This is a Test\n");
}
/*Initialize timer*/
static void Init_timer(struct itimerval *tick)
{
int ret;
memset(tick, 0, sizeof(struct itimerval));
/*
it_value为计时时长,it_interval为定时器的间隔,即第一次计时
it_value时长发送信号,再往后的信号每隔一个it_interval发送一次
*/
/*initialize it_value*/
//定时时间
tick->it_value.tv_sec = COUNT_SEC;
tick->it_value.tv_usec = COUNT_USEC;
/*initialize it_interval*/
//间隔
tick->it_interval.tv_sec = COUNT_SEC;
tick->it_interval.tv_usec = COUNT_USEC;
}
int main(int argc, const char * argv [])
{
int ret = 0;
struct itimerval tick;
signal(SIGALRM, Timer_Test);//接收到定时器产生的SIGALRM信号后,执行Timer_Test()函数
Init_timer(&tick);
ret = setitimer(ITIMER_REAL, &tick, NULL);//ITIMER_REAL:经过指定的时间后,内核将发送SIGALRM信号给本进程
if(ret < 0)
{
perror("setitimer");
return -1;
}
for (;;); //此处循环使主函数不结束。主函数结束后定时函数也将结束。
return 0;
}
小笔记
参考:http://t.csdn.cn/vI4SVhttp://t.csdn.cn/vI4SV