可重入函数

在上一篇介绍了信号的处理过程,那么信号处理过程会从用户态到内核态切换,并且信号处理函数与主控制流是不同的执行流。

一、不可重入函数  

那么就会带来一些问题,例如当你在进行头插node1(p->next=head;head=p;),只执行了第一句(p->next=head;)收到一个信号,并且在这个信号的处理函数中又再次调用头插node2。node2插入成功时,返回主空控制流,接着执行(head=p),那么这个时候很明显node2就没有插入成功。(前提,链表为全局的)

如上面的例子,insert()函数被不同的执行流调用,会造成逻辑错误,那么该函数就是不可重入的,

不可重入:一个函数在被不同的执行流调用时,会造成逻辑错误;

一般符合下列条件很可能是不可重入函数:

1.使用了非const的全局变量或静态变量

2.调用了malloc()或者free(),因为malloc用全局链表管理的

3.调用了标准I/o库函数,因为标准I/O库的很多实现都是以不可重入的方式使用全局数据

4.调用了不可重入函数

(printf()不可重入,只是因为字符串比较短,出错概率低)

二、volatile

看下面代码:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>

int sig_flag=1;

void MyHandler(int sig)
{
    (void)sig;
    sig_flag=0;
}
int main()
{
    signal(SIGINT,MyHandler);
    while(sig_flag);//循环没有做任何事情
    return 0;
}

这里并没有按照我们预期的当捕获到SIGINT信号时,程序就会停下来。

原因是,这里编译代码时候,采用O3级优化代码,这里当编译器在处理时发现while()循环中判断条件sig_flag频繁使用,并且没有做修改,编译器进行优化,将sig_falg 变量放在寄存器中,每次都从寄存器中来取。所以当信号处理函数中将sig_falg修改(改变的是内存中的值),并没有影响寄存器中的值,所以循环条件一直为真。

volatile作用就是防止编译器过度优化导致执行错误,每次从内存中读取变量(其实就是编译器的bug让我们自己来处理)

下一篇中有重点将解https://blog.csdn.net/Misszhoudandan/article/details/81355610

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值