【发布时间】: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