Linux:可重入函数与不可重入函数

5人阅读 评论(0) 收藏 举报

函数是一段载入到内存的代码。函数的代码可长可短,执行时间长度也不确定。在多线程中,线程之间是可以进行切换的。函数是一段写好的代码,属于程序公有的代码段。一个进程中有多个线程,每一个线程都可以调用这段函数代码执行。而在多线程环境中,线程的切换是无法预料的,你不知道下一秒是哪个线程在执行,每时每刻的运行环境都不一样,因为线程切换也是变化莫测的。这是操作系统调度进程线程的范围,不是我们能够掌控的。既然我们无法改变进程调度,无法得知线程切换的规律,那就不要依赖线程的切换。我们的程序要做到,无论线程怎么切换,执行的结果都要一致。而我们该如何才能够达到无论线程如何切换,执行结果都是一致的呢?

重入:重复进入!!!

可重入函数

一个函数在执行的过程中被打断,然后会再被再重头执行一次,执行完后,再回来把刚才没执行完的部分执行完。这就相当于嵌套的执行了。函数是公共代码,这样的执行是允许的。函数的执行可以被打断,打断之后还可以再重头执行,执行完后接着执行刚才没有执行的代码,然后第一次执行的代码(被打断的函数)执行结果还是正确的。也就是说,这个函数执行,无论中间把这个函数再嵌入执行多少遍,怎么嵌入,最终执行完,执行的结果都是正确的,这样的函数就是可重入函数。

我们平常所写的函数,常常都是用的函数内部的局部变量,由于是函数内部的局部变量,那么如果出现了函数在执行的过程中被打断,然后被重头执行,执行完毕后,由于我们使用的都是函数内部的局部变量,而函数执行完毕,会释放在函数内部所创建的局部变量等,这样等我们返回到之前被中断的地方去的时候,就不会影响此时这个函数的内部的变量内容,这样的话,也就是说我们函数为可重入的。

void my_strcpy(*dest, *src)
{
    while(*dest++ = *src++)
    {
        ;
    }
    *dest = '\0';
}

比如,像我们平常所写的这类函数,函数在栈上创建,如果此函数被重入,多次重入时,互相之间并不会影响它们的指针指向。所以在重入时是可以的。

常用的可重入函数的方法有:

1.不要使用全局变量,防止别的代码覆盖这些变量的值。
2.调用这类函数之前先关掉中断,调用完之后马上打开中断。防止函数执行期间被中断进入别的任务执行。
3.使用信号量(互斥条件)。
总而言之:要保证中断是安全的。

不可重入函数

那么不可重入函数显而易见,就是在函数执行期间,被中断,从头执行这个函数,执行完毕后再返回刚才的中断点继续执行,此时由于刚才的中断导致了现在从新在中断点执行时发生了不可预料的错误。那么这类函数就是不可重入函数。

我们知道,在中断函数之后会将中断点的一些数据保存起来,上下文数据等等,那么这些数据不是被保存了吗?怎么还会被影响?其实我们在保存上下文数据的时候,仅仅保存了一小部分,而且那一小部分也只是地址,而对全局变量、静态变量这些并没有保存。所以一旦中断之后,返回到中断点,此时就是不可预料的了。

常见的不可重入函数:

  1. 使用了静态数据结构
  2. 调用了malloc和free等
  3. 调用了标准I/O函数
  4. 进行了浮点运算

malloc与free是不可重入的,它们使用了全局变量来指向堆区。标准I/O大多都使用了全局数据结构。浮点一般都是不可重入的 (浮点运算大多使用协处理器或者软件模拟来实现)。

如何避免写出不可重入函数

不使用或者互斥使用全局变量,不使用静态局部变量,只是用局部变量,在函数中动态分配的内存只在本函数中使用,不会传递函数外使用,只要保证局部特性,函数中使用的所有东西都只有局部性,对外不公开,用完即释放,就可以保证可重入。这样,不管怎么重叠,反正本层的函数的东西只有本层能够使用,其他层的函数无法使用,就相当于隔离每一层的变量。这样,不管重叠多少次,都不可能相互影响。这样每一层函数执行的结果都是正确的。


欢迎大家共同讨论,如有错误及时联系作者指出,并改正。谢谢大家!

查看评论

什么是可重入函数和不可重入函数以及区别

转自:http://www.feijispace.cn/chengxu/106/什么是可重入函数和不可重入函数以及区别在 实时系统的设计中,经常会出现多个任务调用同一个函数的情况。如果这个函数不幸被设...
  • qiushanjushi
  • qiushanjushi
  • 2010年12月21日 20:50
  • 811

不可重入函数总结

1.malloc,free, printf均是不可重入函数(意味不能在中断函数或信号处理函数同时调用),但是线程安全函数(意味它可以被多个线程调用) 2.函数有static变量,则该函数是不可重入函数...
  • zyboy2000
  • zyboy2000
  • 2016年04月11日 12:59
  • 2234

linux可重入函数

可重入函数这一概念早有接触,但一直未有系统的理解,最近阅读《APUE》信号一章时,其中讲解很到位,故总结如下。 信号作为一种软中断,能够被进程给捕获,因而也就中断进程的正常执行,转而去执行信号处理程...
  • velanjun
  • velanjun
  • 2011年12月06日 13:26
  • 1331

可重入函数的深入理解以及printf的可重入性

这个概念在嵌入式操作系统中比较重要,由于存在任务的调度,它实时系统,可剥夺型内核中是危险的,如同一个安静的水雷。可能会被触发,也可能安然无恙。由于它运行结果的不可预期性,会使系统带来隐患。 ...
  • u012138828
  • u012138828
  • 2014年08月28日 21:05
  • 1122

Linux中的可重入函数和不可重入函数

Linux中的可重入函数和不可重入函数                                                           ...
  • ASKLW
  • ASKLW
  • 2016年10月13日 09:13
  • 603

可重入函数与不可重入函数概念以及编写规范

不可重入怎么改改成可重入函数。一个可重入的函数简单来说就是可以被中断的函数,也就是说,可以在这个函数执行的任何时刻中断它,转入OS调度下去执行另外一段代码,而返回控制时不会出现什么错误;而不可重入的函...
  • xy010902100449
  • xy010902100449
  • 2015年06月12日 21:32
  • 2303

Linux可重入函数

1、可重入函数     可重入函数指的是可以被中断的函数。也就是说,可以在这个函数执行的任何时刻中断它,转入OS调度下去执行另外一段代码,而返回控制时不会出现什么错误;而不可重入的函数由于使用了...
  • qq_20480611
  • qq_20480611
  • 2015年11月22日 09:39
  • 585

信号处理函数遇上不可重入函数

123
  • qq_18973645
  • qq_18973645
  • 2017年01月23日 19:10
  • 228

深入理解线程安全和可重入函数

线程安全 基本定义 线程安全:简单来说线程安全就是多个线程并发同一段代码时,不会出现不同的结果,我们就可以说该线程是安全的; 线程不安全:说完了线程安全,线程不安全的问题就很好解...
  • double_happiness
  • double_happiness
  • 2017年06月06日 18:55
  • 871

C语言之可重入函数 && 不可重入函数

转自:http://bubuko.com/infodetail-312842.html 可重入函数      在 实时系统的设计中,经常会出现多个任务调用同一个函数的情况。如果这个函数不幸...
  • ruohuanni
  • ruohuanni
  • 2015年09月18日 21:11
  • 1264
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 1330
    积分: 595
    排名: 9万+
    博客专栏
    文章分类
    文章存档
    最新评论