【问题标题】:C11 thread-safety with respect to functions that return pointers to static buffers关于返回指向静态缓冲区的指针的函数的 C11 线程安全
【发布时间】:2012-02-26 15:53:24
【问题描述】:

考虑像 C 标准库中的 localtime 这样的函数,它返回指向(历史上)静态缓冲区的指针。 C11 是否将这些缓冲区设为线程本地?

根据 C11 中的 7.1.4:

除非在随后的详细描述中明确说明,否则库函数应防止数据竞争,如下所示: 库函数不得直接或间接访问当前线程以外的线程可访问的对象,除非这些对象通过以下方式直接或间接访问函数的参数。库函数不得直接或间接修改当前线程以外的线程可访问的对象,除非这些对象是通过函数的非常量参数直接或间接访问的。如果对象对用户不可见并且受到保护以防止数据竞争,则实现可以在线程之间共享它们自己的内部对象。

localtime 为例。它的返回值指向的struct tm 似乎不符合“内部对象”的条件,因为调用者可以访问它,所以似乎在另一个线程中调用localtime 可能不会破坏先前在第一个线程。这意味着localtime 需要为每个线程使用不同的缓冲区。

然而,标准没有规定返回地址的对象的生命周期结束,我认为没有理由在调用线程终止后继续使用这个struct tm 的程序是无效的。因此,对象不能有线程存储持续时间。

我发现实现可以满足所有要求的唯一方法是到处泄漏内存,这肯定不是预期的。我是否遗漏了一些明显的东西,还是 C11 对遗留接口的线程安全处理真的考虑得这么糟糕?

【问题讨论】:

    标签: c multithreading language-lawyer c11


    【解决方案1】:

    ...unless explicitly stated otherwise7.27.3 Time conversion functions 的介绍性章节明确指出,这些函数不应该避免数据竞争。 (与许多其他库函数一样。)

    在规范性附件 K 的边界检查扩展中有带有 _s 后缀的派生函数,旨在避免竞争条件。

    【讨论】:

    • 好的,我查看了函数的特定文档,但没有查看介绍。看起来你找到了我遗漏的东西。
    • 您可能想补充一点,附件是可选的,实现很少见、不合规和/或效率低下,即使它们会解决那些破坏交易的问题,也有充分的理由拒绝它们。另请参阅tr24731
    猜你喜欢
    • 1970-01-01
    • 2015-09-02
    • 1970-01-01
    • 2010-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多