关于返回静态缓冲区指针的函数的 C11 线程安全

标签 c multithreading language-lawyer c11

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

根据 C11 中的 7.1.4:

Unless explicitly stated otherwise in the detailed descriptions that follow, library functions shall prevent data races as follows: A library function shall not directly or indirectly access objects accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function's arguments. A library function shall not directly or indirectly modify objects accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function's non-const arguments. Implementations may share their own internal objects between threads if the objects are not visible to users and are protected against data races.

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

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

我发现一个实现可以满足所有要求的唯一方法是到处泄漏内存,这肯定不是我们想要的。我是否遗漏了一些明显的东西,或者 C11 对遗留接口(interface)的线程安全处理是否真的考虑不周?

最佳答案

... 除非另有明确说明:7.27.3 时间转换函数 的介绍章节明确指出这些函数不应该避免数据竞争。 (许多其他库函数也是如此。)

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

关于关于返回静态缓冲区指针的函数的 C11 线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9138666/

相关文章:

Java多线程。不同线程上的相同 System.currentTimeMillis() 值

string - 在 Perl 中,为什么 utf-8 字符串在拆分为字符时打印的不同?

c - strncmp 相对于 strcmp 的优势?

c - 如何对正在增长的链表中的 2 个节点进行所有可能的比较

multithreading - 操作系统如何确定应为每个线程分配多少堆栈空间?

rust - `dyn` 与绝对路径一起使用时出现错误 [E0433]

c++ - 非静态成员函数的 std::add_pointer 实现

c - 将外部 C++ 源链接到我的 DLL 库

c - 在C中, '=='是否曾用于变量赋值?

multithreading - 强制挂起的函数在一个线程上工作以在后台映射 Realm 对象