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

参考:

1. 摘自 多线程和多进程的区别(小结) http://blog.csdn.net/hairetz/article/details/4281931

要确保函数线程安全,主要需要考虑的是线程之间的共享变量。

属于同一进程的不同线程会共享进程内存空间中的全局区和堆,而私有的线程空间则主要包括栈和寄存器。

因此,对于同一进程的不同线程来说,每个线程的局部变量都是私有的,而全局变量、局部静态变量、分配于堆的变量都是共享的。在对这些共享变量进行访问时,如果要保证线程安全,则必须通过加锁的方式。

要确保函数可重入,需满足一下几个条件:

1、不在函数内部使用静态或全局数据 
2、不返回静态或全局数据,所有数据都由函数的调用者提供。 
3、使用本地数据,或者通过制作全局数据的本地拷贝来保护全局数据。
4、不调用不可重入函数。

可重入与线程安全并不等同,一般说来,可重入的函数一定是线程安全的,但反过来不一定成立。线程安全函数包括了可重入的函数,但不全是可重入函数;

比如:strtok函数是既不可重入的,也不是线程安全的;加锁的strtok不是可重入的,但线程安全;而strtok_r既是可重入的,也是线程安全的。

如果我们的线程函数不是线程安全的,那在多线程调用的情况下,可能导致的后果是显而易见的——共享变量的值由于不同线程的访问,可能发生不可预料的变化,进而导致程序的错误,甚至崩溃。

可重入函数与不可重入函数

如何将一个不可重入的函数改写成"可重入的函数"?  <根据上面的分析,这里意思包含了线程安全的函数.>
    答:把一个不可重入函数变成可重入的唯一方法是用可重入规则来重写它。其实很简单,只要遵守了几条很容易理解的规则,那么写出来的函数就是可重入的。
    1) 不要使用全局变量。因为别的代码很可能覆盖这些变量值。
    2) 在和硬件发生交互的时候,切记执行类似disinterrupt()之类的操作,就是关闭硬件中断。完成交互记得打开中断,在有些系列上,这叫做“进入/退出核心”。
    3) 不能调用其它任何不可重入的函数。
    4) 谨慎使用堆栈。最好先在使用前先OS_ENTER_KERNAL。

堆栈操作涉及内存分配,稍不留神就会造成益出导致覆盖其他任务的数据,所以,请谨慎使用堆栈!

时间: 2024-10-04 00:56:13

linux: 可重入函数与不可重入函数的相关文章

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

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

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

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). 下面的各种情况会产生一个信号: 当用户在终端按下特定的键时,会产生

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

本文转载自:http://www.cnblogs.com/parrynee/archive/2010/01/29/1659071.html 可重入函数 在 实时系统的设计中,经常会出现多个任务调用同一个函数的情况.如果这个函数不幸被设计成为不可重入的函数的话,那么不同任务调用这个函数时可能修改其他任 务调用这个函数的数据,从而导致不可预料的后果.那么什么是可重入函数呢?所谓可重入是指一个可以被多个任务调用的过程,任务在调用时不必担心数据是否会 出错.不可重入函数在实时系统设计中被视为不安全函数.

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