异步信号安全(可重入性)与线程安全

转载出处 http://www.cnblogs.com/zhaoyl/archive/2012/10/03/2711018.htmlhtml

1. 三个概念,线程安全,可重入,信号安全程序员

  先简单提一下,   线程安全,主要是针对数据竞争来讲的,就是说:若是数据不须要共享,那就让每一个线程私有;若是须要共享,那就加锁。   信号安全,其实也就是异步信号安全,是说线程在信号处理函数当中,无论以任何方式调用你的这个函数若是不死锁不修改数据,那就是信号安全的。也就是说一个可重入函数在信号处理函数当中不影响调用他的人自己的状态,其实就是一个task_struct有不少指针指向它,你经过多线程调一个可重入函数,函数有本身所在的task的代码段和数据段,若是你在信号处理里面调它,其实是换了一个指向同一个task_struct里面内容的指针来操做,会有问题。这种情形经过加锁是解决不了问题的,好比你正在调用printf过程当中,遇到一个信号,转而去处理这个信号,而且在处理这个信号的信号处理函数当中正巧要调用printf,那么屏幕上就是乱的,加锁行不行呢?那就很好玩了。因此printf不是异步信号安全的。   可重入性:就是不管以什么方式屡次调用都不会出现问题,不会出现对可能有修改的静态数据的访问,不会出现对全局变量(好比errno)的访问。严格讲可重入要区分线程安全(弱可重入)仍是信号安全(强可重入)两点,可是通常说可重入就是指信号安全。因为信号安全要求高于线程安全,因此说若是一个函数是可重入的,那必定是线程安全的(反之不必定)。 2.  下面详细解释三者   2.1 可重入性(reentrant)针对函数,它有两个方面的内涵:   1)可并行/并发,同时进入:指可重入函数被某任务调用时,其它任务可同时进行调用而不产生错误的结果;或称在相同的输入状况下可重入函数的执行所产生的效果,并不因其并发的调用而产生不一样,也称并发安全。   2)中断后可从新进入:指可重入函数可被任意的中断,当中断执行完毕,返回断点能够继续正确的运行下去;或称在相同的输入状况下可重入函数的执行所产生的结果,并不由于在函数执行期间有中断的调用而产生不一样,也称中断安全。   可重入(reentrant)函数能够由多于一个任务并发使用,而没必要担忧数据错误。相反, 不可重入(non-reentrant)函数不能由超过一个任务所共享,除非能确保函数的互斥 (或者使用信号量,或者在代码的关键部分禁用中断)。可重入函数能够在任意时刻被中断, 稍后再继续运行,不会丢失数据。可重入函数要么使用本地变量,要么在使用全局变量时 保护本身的数据。   可重入函数通常要知足: 不为连续的调用持有静态数据。 不返回指向静态数据的指针;全部数据都由函数的调用者提供。 使用本地数据,或者经过制做全局数据的本地拷贝来保护全局数据。 毫不调用任何不可重入函数。    出于如下任意某个缘由,其他函数是不可重入的: 它们调用了 malloc 或 free:malloc/free 是在 C 标准中规定的,而在 C 中是没有进程/线程的概念。 众所周知它们使用了静态数据结构体。 它们是标准 I/O 程序库的一部分:glibc的c库算是线程安全了,却不保证可重入或异步信号安全。   2.2 线程安全(MT-safe)不只仅针对函数,它主要是指数据或程序的安全这一结果,因此有不一样的层次上讲的线程安全:如线程安全的函数,线程安全的库 。本文还会引入线程安全的类这一律念。一般意义上一个线程安全的函数是指有可重入函数第一个内涵的函数即并发安全的函数。但须要注意的是即便是一个从函数级别上并不安全的函数,若是使其不安全的因素在特定应用中并不存在时,这个函数对于该应用来说一样也是线程安全的。例如对于全局变量的访问,通常而言未命名同步方式访问确定是非线程安全的,但若是全部可能同时发生的访问均是只读访问则从结果上讲也是线程安全的。   不要混淆可重入与线程安全。在程序员看来,这是两个独立的概念:函数能够是可重入的,是线程安全的,或者 两者皆是,或者两者皆非。不可重入的函数不能由多个线程使用。另外,或许不可能让某个 不可重入的函数是线程安全的。关于标准IO库是否是线程安全的要依据实际状况而定,不一样的库有不一样实现,通常为了方便用户使用,在支持多线程的系统上都配备了线程安全的库,但却不是以不安全的,由于,信号必定是异步的,不是线程的加锁机制(本质是同步化)就能够解决的。   2.3 信号安全,信号的本质软中断,中断在本质上是异步的,所谓异步信号安全同线程安全同样,也是站在结果上考虑的,指在信号的中断处理过程当中的安全。一般意义上一个异步信号安全的函数是指能够在异步信息处理函数中调用而不会出现异常的函数。一样须要注意到即便一个从函数级别上并不是异步信息安全的函数,若是在信息处理函数中调用,也并不必定会产生不安全的结果。 3. 三个概念的异同    从函数级别考虑,仅从概念上就能够发现可重入函数必定是线程安全函数,也是异步信号安全函数;多线程安全函数却要弱得多,并不是必定要是可重入函数,它只要求并发无误便可;虽然异步信号函数与可重入函数的描述方式有所不一样,但二者从实现层面上讲是彻底一致的。   参考文献: 1 《使用可重入函数进行更安全的信号处理》 2 http://bbs.chinaunix.net/thread-942090-1-1.html
相关文章
相关标签/搜索