一:概念
(1)所谓的可重入函数:就是我们在信号处理函数中 调用它 是安全的;可重入函数,即在信号处理程序中保证调用安全的函数,这些函数是可重入的并被称为异步信号安全的;比如,malloc就是一个不可重入函数,当我们在主函数当中调用它时,如果,它还没处理结束(和内部的实现有关),这个时候,又来了一个信号,而我们又在信号处理函数当中去调用malloc,这个时候,由于malloc自己内部实现的原因,可能要用到某个全局变量等,由于在主函数当中还没结束调用,所以,就会在信号处理函数当中出现异常的情况。
处理信号程序流程:
二:不可重入函数使用建议
//在写信号处理函数的时候,要注意的事项:
(a)在信号处理函数中,尽量使用简单的语句做简单的事情,尽量不要调用系统函数以免引起麻烦;
(b)如果必须要在信号处理函数中调用一些系统函数,那么要保证在信号处理函数中调用的 系统函数一定要是可重入的;
©如果必须要在信号处理函数中调用那些可能修改errno值的可重入的系统函数,那么 就得事先备份errno值,从信号处理函数返回之前,将errno值恢复;
例如:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
//信号处理函数
void sig_usr(int signo)
{
//先保存errno的值,
int myerrno = errno;
if(signo == SIGUSR1)
{
printf("收到了SIGUSR1信号!\n");
}
else if(signo == SIGUSR2)
{
printf("收到了SIGUSR2信号!\n");
}
else
{
printf("收到了未捕捉的信号%d!\n",signo);
}
//最后进行恢复
errno = myerrno;
}
int main(int argc, char *const *argv)
{
if(signal(SIGUSR1,sig_usr) == SIG_ERR) //系统函数,参数1:是个信号,参数2:是个函数指针,代表一个针对该信号的捕捉处理函数
{
printf("无法捕捉SIGUSR1信号!\n");
}
if(signal(SIGUSR2,sig_usr) == SIG_ERR)
{
printf("无法捕捉SIGUSR2信号!\n");
}
for(;;)
{
sleep(1); //休息1秒
printf("休息1秒\n");
}
printf("再见!\n");
return 0;
}
三:不可重入函数范例演示
范例一:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
int g_mysign = 0;
//我这个函数能够修改这个全局变量g_mysign的值
void muNEfunc(int value)
{
//.....其他处理代码
g_mysign = value;
//.....其他处理代码
}
//信号处理函数
void sig_usr(int signo)
{
muNEfunc(22); //因为一些实际需求必须要在sig_user这个信号处理函数里调用muNEfunc
int myerrno = errno;
if(signo == SIGUSR1)
{
printf("收到了SIGUSR1信号!\n");
}
else if(signo == SIGUSR2)
{
printf("收到了SIGUSR2信号!\n");
}
else
{
printf("收到了未捕捉的信号%d!\n",signo);
}
}
int main(int argc, char *const *argv)
{
if(signal(SIGUSR1,sig_usr) == SIG_ERR) //系统函数,参数1:是个信号,参数2:是个函数指针,代表一个针对该信号的捕捉处理函数
{
printf("无法捕捉SIGUSR1信号!\n");
}
if(signal(SIGUSR2,sig_usr) == SIG_ERR)
{
printf("无法捕捉SIGUSR2信号!\n");
}
for(;;)
{
sleep(1); //休息1秒
printf("休息1秒\n");
/*我们希望在调用muNEfunc函数以后,得到g_mysign的值为15,
但是,如果在执行完muNEfunc函数以后,突然来了一个信号,这时
程序执行流程到了信号处理函数当中,而信号处理函数又对muNEfunc
当中的g_mysign变量的值做出了改变,所以,当信号处理函数执行完毕以后
再次回到主函数当中时,g_mysign的值便不是我们所希望的了*/
muNEfunc(15);
printf("g_mysign=%d\n",g_mysign);
//拿g_mysign做一些其他用途;
}
printf("再见!\n");
return 0;
}
范例二:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
//信号处理函数
void sig_usr(int signo)
{
//这里也malloc,这是错用,不可重入函数不能用在信号处理函数中;
int* p;
p = (int *) malloc (sizeof(int)); //用了不可重入函数;
free(p);
if(signo == SIGUSR1)
{
printf("收到了SIGUSR1信号!\n");
}
else if(signo == SIGUSR2)
{
printf("收到了SIGUSR2信号!\n");
}
else
{
printf("收到了未捕捉的信号%d!\n",signo);
}
}
int main(int argc, char *const *argv)
{
/*系统函数,参数1:是个信号,参数2:是个函数指针,代表一个针对该信号的捕捉处理函数*/
if(signal(SIGUSR1,sig_usr) == SIG_ERR)
{
printf("无法捕捉SIGUSR1信号!\n");
}
if(signal(SIGUSR2,sig_usr) == SIG_ERR)
{
printf("无法捕捉SIGUSR2信号!\n");
}
for(;;)
{
int* p;
p = (int *) malloc (sizeof(int));
free(p);
}
printf("再见!\n");
return 0;
}
在信号处理函数当中调用了,不不可重入函数以后,发现后面就收不到SIGUSER1信号了.
版权声明:本文为qq_38158479原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。