您的位置:首页 > 编程语言 > C语言/C++

可重入函数

2015-09-16 14:50 232 查看

可重入函数

当捕捉到信号时,不论进程的主控制流程当前执行到哪儿,都会先跳到信号处理函数中执行,从信号处理函数返回后再继续执行主控制流程。信号处理函数是一个单独的控制流程,因为它和主控制流程是异步的,二者不存在调用和被调用的关系,并且使用不同的堆栈空间。引入了信号处理函数使得一个进程具有多个控制流程,如果这些控制流程访问相同的全局资源(全局变量、硬件资源等),就有可能出现冲突,如下面的例子所示。

图 33.3. 不可重入函数



main
函数调用
insert
函数向一个链表
head
中插入节点
node1
,插入操作分为两步,刚做完第一步的时候,因为硬件中断使进程切换到内核,再次回用户态之前检查到有信号待处理,于是切换到
sighandler
函数,
sighandler
也调用
insert
函数向同一个链表
head
中插入节点
node2
,插入操作的两步都做完之后从
sighandler
返回内核态,再次回到用户态就从
main
函数调用的
insert
函数中继续往下执行,先前做第一步之后被打断,现在继续做完第二步。结果是,
main
函数和
sighandler
先后向链表中插入两个节点,而最后只有一个节点真正插入链表中了。
像上例这样,
insert
函数被不同的控制流程调用,有可能在第一次调用还没返回时就再次进入该函数,这称为重入,
insert
函数访问一个全局链表,有可能因为重入而造成错乱,像这样的函数称为不可重入函数,反之,如果一个函数只访问自己的局部变量或参数,则称为可重入(
Reentrant
)函数。想一下,为什么两个不同的控制流程调用同一个函数,访问它的同一个局部变量或参数就不会造成错乱?
如果一个函数符合以下条件之一则是不可重入的:

调用了
malloc
free
,因为
malloc
也是用全局链表来管理堆的。

调用了标准I/O库函数。标准I/O库的很多实现都以不可重入的方式使用全局数据结构。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C C++