浅谈函数的重入与不可重入

在学习Linux信号以后,我看到这样的一个代码。

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

int a = 0;
int b = 0;

void add()
{
        a++;
        sleep(5);
        b++;
        printf("a+b = %d\n",a+b);
}

void sigcb(int signo)
{
        add();
}

int main()
{
        signal(SIGINT,sigcb); //信号处理
        add();
        return 0;
}

对于以上代码,我们主观意识总是,先执行signal函数间接调用add函数,接着调用add函数。因此结果为2,4。结果真的是这样吗?
在这里插入图片描述
我们来看一下结果为啥会是3,4呢?
在这里插入图片描述
产生的原因: a++,与b++过程不是一次性完成。

多个执行流,同时进入一个函数执行功能 函数的重入

多个执行流竞争执行函数时,如果执行一个函数运行的结果不存在二义性,则称这个函数为可重入函数

反之,如果一个函数在多个执行流中,结果存在二义性,则称函数为不可重入函数

判断基准
一个函数被多个执行流同时执行时,会不会产生数据二义性。

常见不可重入的情况:

  • 调用malloc/free函数,malloc函数是使用全局链表进行管理堆资源的。
  • 调用标准I/O函数
  • 函数中使用静态成员或者全局变量。

常见可重入情况:

  • 没有使用全局变量或者静态变量
  • 不使用malloc/new开辟出空间的
  • 不调用不可重入函数
  • 不返回静态或者全局数据

重入于线程安全

  • 函数是可重入的,则其为线程安全
  • 如果函数是不可重入,则不能适用于多线程,容易产生线程安全问题
  • 如果一个函数中使用全局变量,则该函数既不是线程安全的,也不是可重入的
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值