【问题标题】:POSIX extended definition of reentrancy covering thread-safetyPOSIX 扩展的可重入定义,涵盖线程安全
【发布时间】:2013-05-31 07:25:44
【问题描述】:

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

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

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

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

【问题讨论】:

  • 我认为它的关键字“交错”会有所不同;线程安全部分是顺序的,或者必须是而不是真正交错的。只是猜测......
  • 我会说 POSIX 方面,可重入意味着线程安全,但不一定反过来。但是,我知道的唯一示例来自 Windows 实现的不可重入 C 函数,例如 strtok():它们的实现是线程安全的,因为它使用线程本地存储,但它不是可重入的。我不知道这些函数(或其某些实现)的 POSIX 版本是否是线程安全的。
  • @AnsgarWiechers 这个问题是关于 POSIX.1c 定义的吗?不...

标签: c multithreading concurrency thread-safety posix


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    线程安全代码不需要序列化并发执行,因此我会说根据您引用的 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()设置的值相等,可以更大,但该函数仍然是线程安全的。

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多