POSIX Safety Concepts
这是按照 gun libc 1.2.2.1 POSIX Safety Concepts 中的方式总结的,本节给出各种概念的解释。
包括:
一、Thread-safety
二、Async-signal-safety and reentrancy
三、Async-cancel-safety
Thread-safety 和 Async-signal-safety 相同点
Thread-safety、Reentrancy、Async-signal-safety,都是基于一个相同的场景:
同一个函数被重复执行,导致了race。
APUE 中的 definition
有的地方,将这种情况称为"重入",比如:
APUE 12.5 Reentrancy给出的definition如下:
If a function is reentrant with respect to multiple threads, we say that it is thread-safe. This doesn’t tell us, however, whether the function is reentrant with respect to signal handlers. We say that a function that is safe to be reentered from an asynchronous signal handler is async-signal safe. We saw the async-signal safe functions in Figure 10.4 when we discussed reentrant functions in Section 10.6.
APUE 10.6 Reentrant Functions给出的definition如下:
The Single UNIX Specification specifies the functions that are guaranteed to be safe to call from within a signal handler. These functions are reentrant and are called async-signal safe by the Single UNIX Specification. Besides being reentrant, they block any signals during operation if delivery of a signal might cause inconsistencies.
基于APUE中的definition,我们可以得出如下结论:
1、"If a function is reentrant with respect to multiple threads, we say that it is thread-safe"
多个线程在相同的时刻,调用同一个函数
2、"A function that is safe to be reentered from an asynchronous signal handler is async-signal safe"
调用signal handler,而中断正在执行的函数,在signal handler中调用与被中断函数相同的函数,这就是重入
但是,在很多地方,Reentrancy**都特指 ***async-signal safe*,比如 wikipedia Reentrancy (computing) 中,因此后续为了区分,我们最好使用: Thread-safety、Async-signal-safety。
Reentrancy VS thread safety
两者是正交的概念,描述的是不同的性质;
共同点
两者的深层原因有些类似,一句话来概括就是"race condition",下面是详细的分析:
1、execution flow会不受控制地被suspend/preempt/interrupt
2、可以使用multiple model进行分析,存在race condition: many to one
因此,从many to one来出发,结合各自可能的场景,就可以非常容易的辨明是否Reentrancy、是否thread safety。
3、两者都是reentrant,参见 Programming\Book-APUE\APUE-Reentrant-and-async-signal-safe-and-thread-safe
章节
差异点
两种本质的差异在于:
一、Reentrancy是非multitasking时代的产物,它的function不是由多个thread同时执行的,ISR是由kernel执行的;而thread safety是multitasking时代的产物,它的function是由多个thread同时执行的
NOTE: 关于这一点,参见 wikipedia Reentrancy (computing) # Background # Reentrancy VS thread-safety 段。
二、由于两者的上述本质的差异,因此实现保护"the one"的手段也是不同的
a、mutex可以用于实现thread safety,但是无法实现Reentrancy(不能用于ISR)
b、使用thread local来将the one变为private,可以能够实现thread safety,但是无法实现Reentrancy
具体案例参见: wikipedia Reentrancy (computing) # Thread-safe but not reentrant。
c、两者都可以使用atomicity来保护"the one"
在 wikipedia Reentrancy (computing) 中的几个example是非常好的。
素材
在下面章节中,也对这个topic进行了讨论:
1、programming-language\docs\C++\Resource-management\Memory\Dynamic-allocation\new-operator\Thread-safety-Reentrancy
2、programming-language\docs\C++\Resource-management\Memory\Dynamic-allocation\malloc\Thread-safety-Reentrancy
3、stackoverflow Why are malloc() and printf() said as non-reentrant?
这篇文章 非常好
Thread-safety 和 Async-cancel-safety
它们两个都和thread相关,在 man-7-pthreads
对它们都进行了介绍
pthreads(7) # Async-cancel-safe functions
pthreads(7) # Thread-safe functions
draft
不使用async-signal unsafe function
当然有些情况下的race condition是通过OS提供的各种方法是无法avoid,比如在APUE 的10.6 Reentrant Functions章节介绍的情况,这种情况下,就只有不使用这些async-signal unsafe function才能够彻底规避;
思考:原子操作有哪些优良性质