可重入性和线程安全

原文链接:http://blog.csdn.net/lovekatherine/article/details/1544644 

另一篇相关文章:http://blog.csdn.net/feiyinzilgd/article/details/5811157



    刚翻译完一篇《writing reentrant and thread-safe code》,又通过google和水木搜集了一些资料,故对今天所新学到的只是做个简要的总结,以防看了就忘。


    首先,可重入和线程安全是两个并不等同的概念,一个函数可以是可重入的,也可以是线程安全的,可以两者均满足,可以两者皆不满组(该描述严格的说存在漏洞,参见第二条)。

    其次,从集合和逻辑的角度看,可重入是线程安全的子集,可重入是线程安全的充分非必要条件。可重入的函数一定是线程安全的,然过来则不成立。

    第三,POSIX 中对可重入和线程安全这两个概念的定义:
   
    Reentrant Function:

    A function whose effect, when called by two or more threads,is guaranteed to be as if the threads each executed thefunction one after another in an undefined order, even ifthe actual execution is interleaved.

                                                                                                        From IEEE Std 1003.1-2001 (POSIX 1003.1)
                                                                                                                                      -- Base Definitions, Issue 6
    Thread-Safe Function
     
    A function that may be safely invoked concurrently by multiple threads.

   另外还有一个 Async-Signal-Safe的概念

    Async-Signal-Safe Function:
     
    A function that may be invoked, without restriction fromsignal-catching functions. No function is async-signal -safe unless explicitly described as such.

    以上三者的关系为:
   
    Reentrant Function 必然是Thread-Safe FunctionAsync-Signal-Safe Function
 
  
可重入与线程安全的区别体现在能否在signal处理函数中被调用的问题上,可重入函数在signal处理函数中可以被安全调用,因此同时也是Async-Signal-Safe Function;而线程安全函数不保证可以在signal处理函数中被安全调用,如果通过设置信号阻塞集合等方法保证一个非可重入函数不被信号中断,那么它也是Async-Signal-Safe Function。

     值得一提的是POSIX 1003.1的System Interface缺省是Thread-Safe的,但不是Async-Signal-Safe的。Async-Signal-Safe的需要明确表示,比如fork ()和signal()。

最后让我们来构想一个线程安全但不可重入的函数:

   假设函数func()在执行过程中需要访问某个共享资源,因此为了实现线程安全,在使用该资源前加锁,在不需要资源解锁。

   假设该函数在某次执行过程中,在已经获得资源锁之后,有异步信号发生,程序的执行流转交给对应的信号处理函数;再假设在该信号处理函数中也需要调用函数func(),那么func()在这次执行中仍会在访问共享资源前试图获得资源锁,然而我们知道前一个func()实例已然获得该锁,因此信号处理函数阻塞——另一方面,信号处理函数结束前被信号中断的线程是无法恢复执行的,当然也没有释放资源的机会,这样就出现了线程和信号处理函数之间的死锁局面。

    因此,func()尽管通过加锁的方式能保证线程安全,但是由于函数体对共享资源的访问,因此是非可重入。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值