2

考虑 POSIX 对可重入性的以下扩展定义:

在 POSIX.1c 中,“可重入函数”被定义为“当被两个或更多线程调用时,保证其效果就像线程每个都以未定义的顺序一个接一个地执行函数一样,即使实际执行是交错的”(ISO/IEC 9945:1-1996, §2.2.2)。

来源:http ://www.unix.org/whitepapers/reentrant.html

由于线程安全函数确实序列化并发执行,因此“每个线程都以未定义的顺序依次执行函数,即使实际执行是交错的”,这是否意味着线程安全函数是可重入的(仅考虑 POSIX 定义)?

4

3 回答 3

3

不,线程安全函数不一定是可重入的。

例如,考虑一个具有某种内部状态的函数,该函数受互斥体保护,从而使其成为线程安全的。但是,如果该函数被调用,呃,从同一个线程重入,就会发生死锁。这种函数的一个常见示例是 malloc();malloc 是线程安全的,但不是可重入的,例如,为什么不应该从信号处理程序中调用 malloc。

于 2013-05-31T13:48:16.417 回答
1

线程安全代码不需要序列化并发执行,因此我会说根据您引用的 POSIX 定义,线程安全函数不需要可重入。

考虑以下示例。你有两个线程安全的函数:

void inc_count(struct counter* cnt);
int get_count(struct counter* cnt);

您可以使用这两个来定义另一个线程安全函数:

inc inc_and_get_count(struct counter* cnt) {
   inc_count(cnt);
   return get_count(cnt);
}

此类函数的协定不保证返回值将等于 inc_count() 设置的值,它可以更大,但该函数仍然是线程安全的。

但是根据定义它不是可重入的,来自两个不同线程的两次函数调用可以返回相同的值,如果执行被序列化,则永远不会出现这种情况。

于 2013-05-31T10:47:38.963 回答
1

不,可重入性和线程安全性是函数的正交属性。可重入函数的 POSIX.1c 定义并不意味着线程安全,因为函数可能是可重入的、线程安全的,或者两者都不是。可重入函数仅通过修改其他调用所依赖的状态来保证调用不会相互干扰,而不是那些调用必须是线程安全的。

于 2013-06-01T23:56:34.057 回答