可重入函数与不可重入函数【转】

本文转载自:http://www.cnblogs.com/parrynee/archive/2010/01/29/1659071.html

可重入函数

在 实时系统的设计中,经常会出现多个任务调用同一个函数的情况。如果这个函数不幸被设计成为不可重入的函数的话,那么不同任务调用这个函数时可能修改其他任 务调用这个函数的数据,从而导致不可预料的后果。那么什么是可重入函数呢?所谓可重入是指一个可以被多个任务调用的过程,任务在调用时不必担心数据是否会 出错。不可重入函数在实时系统设计中被视为不安全函数。

满足下列条件的函数多数是不可重入的:

(1)函数体内使用了静态的数据结构;

(2)函数体内调用了malloc()或者free()函数;

(3)函数体内调用了标准I/O函数。

如何写出可重入的函数?在函数体内不访问那些全局变量,不使用静态局部变量,坚持只使用缺省态(auto)局部变量,写出的函数就将是可重入的。如果必须访问全局变量,记住利用互斥信号量来保护全局变量。或者调用该函数前关中断,调用后再开中断。

可重入函数可以被一个以上的任务调用,而不必担心数据被破坏。可重入函数任何时候都可以被中断,一段时间以后又可以运行,而相应的数据不会丢失。可重入函数或者只使用局部变量,即保存在CPU寄存器中或堆栈中;或者使用全局变量,则要对全局变量予以保护。

说法2:

一个可重入的函数简单来说,就是:可以被中断的函数。就是说,你可以在这个函数执行的任何时候中断他的运行,在任务调度下去执行另外一段代 码而不会出现什么错误。而不可重入的函数由于使用了一些系统资源,比如全局变量区,中断向量表等等,所以他如果被中断的话,可能出现问题,所以这类函数是 不能运行在多任务环境下的。

基本上下面的函数是不可重入的
(1)函数体内使用了静态的数据结构;

(2)函数体内调用了malloc()或者free()函数;

(3)函数体内调用了标准I/O函数。

把一个不可重入函数变成可重入的唯一方法是用可重入规则来重写他。
其实很简单,只要遵守了几条很容易理解的规则,那么写出来的函数就是可重入的。

第一,不要使用全局变量。因为别的代码很可能覆盖这些变量值。

第二,在和硬件发生交互的时候,切记执行类似disinterrupt()之类的操作,就是关闭硬件中断。完成交互记得打开中断,在有些系列上,这叫做“进入/退出核心”或者用OS_ENTER_KERNAL/OS_EXIT_KERNAL来描述。//这是临界区保护

第三,不能调用任何不可重入的函数。

第四,谨慎使用堆栈。最好先在使用前先OS_ENTER_KERNAL。

还有一些规则,都是很好理解的,总之,时刻记住一句话:保证中断是安全的!

时间: 2024-10-26 17:06:12

可重入函数与不可重入函数【转】的相关文章

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

参考: 1. 摘自 多线程和多进程的区别(小结) http://blog.csdn.net/hairetz/article/details/4281931 要确保函数线程安全,主要需要考虑的是线程之间的共享变量. 属于同一进程的不同线程会共享进程内存空间中的全局区和堆,而私有的线程空间则主要包括栈和寄存器. 因此,对于同一进程的不同线程来说,每个线程的局部变量都是私有的,而全局变量.局部静态变量.分配于堆的变量都是共享的.在对这些共享变量进行访问时,如果要保证线程安全,则必须通过加锁的方式. 要

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

1.定义 一个可重入的函数简单来说就是可以被中断的函数,也就是说,可以在这个函数执行的任何时刻中断它,转入OS调度下去执行另外一段代码,而返回控制时不会出现什么错误:而不可重入的函数由于使用了一些系统资源,比如全局变量区,中断向量表等,所以它如果被中断的话,可能会出现问题,这类函数是不能运行在多任务环境下的. 换句话说,我们也可以这样理解,重入即表示重复进入,首先它意味着这个函数可以被中断,其次意味着它除了使用自己栈上的变量以外不依赖于任何环境(包括static),这样的函数就是 purecod

函数的可重入性、线程安全函数、异步信号安全函数

重入即表示重复进入,首先它意味着这个函数可以被中断,其次意味着它除了使用自己栈上的变量以外不依赖于任何环境(包括static),这样的函数就是purecode(纯代码)可重入,可以允许有该函数的多个副本在运行,由于它们使用的是分离的栈,所以不会互相干扰.,常见的情况是,程序执行到某个函数foo()时,收到信号,于是暂停目前正在执行的函数,转到信号处理函数,而这个信号处理函数的执行过程中,又恰恰也会进入到刚刚执行的函数foo(),这样便发生了所谓的重入.此时如果foo()能够正确的运行,而且处理完

操作系统--可重入函数和不可重入函数

可重入函数主要用于多任务环境中,简单来说就是可以被中断的函数,即在这个函数执行的任何时刻中断它,转入OS调度下去执行另外一段代码,返回控制时不会出现什么错误:也意味着它除了使用自己栈上的变量以外不依赖于任何环境(包括static),这样的函数就是 purecode(纯代码)可重入,可以允许有该函数的多个副本在运行,由于它们使用的是分离的栈,所以不会互相干扰.而不可重入的函数由于使用了一些系统资源,比如全局变量区.中断向量表等,所以它如果被中断的话,可能会出现问题,这类函数是不能运行在多任务环境下

UNIX高级环境编程(13)信号 - 概念、signal函数、可重入函数

信号就是软中断. 信号提供了异步处理事件的一种方式.例如,用户在终端按下结束进程键,使一个进程提前终止. ? 1 信号的概念 每一个信号都有一个名字,它们的名字都以SIG打头.例如,每当进程调用了abort函数时,都会产生一个SIGABRT信号. 每一个信号对应一个正整数,定义在头文件<signal.h>中. 没有信号对应整数0,kill函数使用信号编号0表示一种特殊情况,所以信号编号0又叫做空信号(null signal). 下面的各种情况会产生一个信号: 当用户在终端按下特定的键时,会产生

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

在实时系统的设计中,经常会出现多个任务调用同一个函数的情况.如果有一个函数不幸被设计成为这样:那么不同任务调用这个函数时可能修改其他任务调用这个函数的数据,从而导致不可预料的后果.这样的函数是不安全的函数,也叫不可重入函数. 相反,肯定有一个安全的函数,这个安全的函数又叫可重入函数.那么什么是可重入函数呢?所谓可重入是指一个可以被多个任务调用的过程,任务在调用时不必担心数据是否会出错. 一个可重入的函数简单来说就是可以被中断的函数,也就是说,可以在这个函数执行的任何时刻中断它,转入OS调度下去执

C语言可重入函数和不可重入函数

可重入函数 在 实时系统的设计中,经常会出现多个任务调用同一个函数的情况.如果这个函数不幸被设计成为不可重入的函数的话,那么不同任务调用这个函数时可能修改其他任 务调用这个函数的数据,从而导致不可预料的后果.那么什么是可重入函数呢?所谓可重入是指一个可以被多个任务调用的过程,任务在调用时不必担心数据是否会 出错.不可重入函数在实时系统设计中被视为不安全函数. 满足下列条件的函数多数是不可重入的: (1)函数体内使用了静态的数据结构: (2)函数体内调用了malloc()或者free()函数: (

可重入函数和不可重入函数

个函数在被调用执行期间(尚未调用结束),由于某种时序又被重复调用,称之为"重入".根据函数实现的方法可分为"可重入函数"和"不可重入函数"两种.看如下时序. 显然,insert函数是不可重入函数,重入调用,会导致意外结果呈现.究其原因,是该函数内部实现使用了全局变量. 注意事项 定义可重入函数,函数内不能含有全局变量及static变量,不能使用malloc.free 信号捕捉函数应设计为可重入函数 信号处理程序可以调用的可重入函数可参阅man 7

信号处理函数误用不可重入函数导致的进程死锁情况

记一次进程死锁的情况: 某天突然发现进程不再运行处理且有没有崩溃产生core文件: 使用gdb -p pid查看堆栈信息如下: 1 #0 0x000000376faf83ae in __lll_lock_wait_private () from /lib64/libc.so.6 2 #1 0x000000376fa7d35b in _L_lock_10288 () from /lib64/libc.so.6 3 #2 0x000000376fa7ab83 in malloc () from /l