可重入函数和不可重入函数 点击:871 | 回复:0



rainbow

    
  • 精华:0帖
  • 求助:0帖
  • 帖子:3帖 | 0回
  • 年度积分:0
  • 历史总积分:59
  • 注册:2007年8月13日
发表于:2007-11-02 17:08:00
楼主

如果要对函数进行并发访问,不管是通过线程还是通过进程,您都可能会到函数不可重入所导致的问题。在本文中,通过示例代码了解如果可重入性不能得到保证会产生何种异常,尤其要注意信号。引入了五条可取的编程经验,并对提出的编译器模型进行了讨论。

http://www.ahaoz.com/Article/203/576/2005/20051120105207.html 

在早期的编程中,不可重入性对程序员并不构成威胁;函数不会有并发访问,也没有中断。在很多较老的 C 语言实现中,函数被认为是在单线程进程的环境中运行。

  不过,现在,并发编程已普遍使用,您需要意识到这个缺陷。本文描述了在并行和并发程序设计中函数的不可重入性导致的一些潜在问题。信号的生成和处理尤其增加了额外的复杂性。由于信号在本质上是异步的,所以难以找出当信号处理函数触发某个不可重入函数时导致的 bug。

本文:

  • 定义了可重入性,并包含一个可重入函数的 POSIX 清单。
  • 给出了示例,以说明不可重入性所导致的问题。
  • 指出了确保底层函数的可重入性的方法。
  • 讨论了在编译器层次上对可重入性的处理。

什么是可重入性?
可重入(reentrant)函数可以由多于一个任务并发使用,而不必担心数据错误。相反,不可重入(non-reentrant)函数不能由超过一个任务所共享,除非能确保函数的互斥(或者使用信号量,或者在代码的关键部分禁用中断)。可重入函数可以在任意时刻被中断,稍后再继续运行,不会丢失数据。可重入函数要么使用本地变量,要么在使用全局变量时保护自己的数据。

可重入函数:

  • 不为连续的调用持有静态数据。
  • 不返回指向静态数据的指针;所有数据都由函数的调用者提供。
  • 使用本地数据,或者通过制作全局数据的本地拷贝来保护全局数据。
  • 绝不调用任何不可重入函数。

不要混淆可重入与线程安全。在程序员看来,这是两个独立的概念:函数可以是可重入的,是线程安全的,或者二者皆是,或者二者皆非。不可重入的函数不能由多个线程使用。另外,或许不可能让某个不可重入的函数是线程安全的。

IEEE Std 1003.1 列出了 118 个可重入的 UNIX 函数,在此没有给出副本。参见 linux/l-reent.shtml#resources">参考资料中指向 unix.org 上此列表的链接。

出于以下任意某个原因,其余函数是不可重入的:

  • 它们调用了 mallocfree
  • 众所周知它们使用了静态数据结构体。
  • 它们是标准 I/O 程序库的一部分。的函数不能由多个线程使用。另外,或许不可能让某个不可重入的函数是线程安全的。


热门招聘
相关主题

官方公众号

智造工程师