为什么 GNU GLIBC strsignal() 在现代操作系统上被认为是线程不安全的?

问题描述 投票:0回答:1

背景

首先,我知道

strsignal()
不是线程安全的一般原因是标准说它可能不是。
strsignal()
GNU C 标准库函数是在 POSIX 规范中定义的,在该规范中它说:

strsignal() 函数不需要是线程安全的。

https://pubs.opengroup.org/onlinepubs/9699919799.2016edition/functions/strsignal.html

由于标准不要求

strsignal()
是线程安全的,因此使用此函数的代码 不能假设它是线程安全的,除非使用的特定实现指定它是线程安全的。

例如,POSIX 规范规定

strerror()
可能不是线程安全的,但 glibc 2.32 中的更改意味着在较新版本的 glibc 中,此函数现在是线程安全的,并且在
man 3 strerror
上如此列出。

https://lists.gnu.org/archive/html/info-gnu/2020-08/msg00002.html

问题

GNU linux 版本的 C 标准库函数

strsignal()
的手册页指定该函数是线程不安全的:

Linux 手册页 6.7

man 3 strsignal

┌───────────────────────────────┬───────────────┬─────────────────────────────────┐
│ Interface                     │ Attribute     │ Value                           │
├───────────────────────────────┼───────────────┼─────────────────────────────────┤
│ strsignal()                   │ Thread safety │ MT-Unsafe race:strsignal locale │
├───────────────────────────────┼───────────────┼─────────────────────────────────┤
│ sigdescr_np(), sigabbrev_np() │ Thread safety │ MT-Safe                         │
└───────────────────────────────┴───────────────┴─────────────────────────────────┘

但是,查看源代码可以发现,专门针对 glibc 表明,自 2.32 起

strsignal()
使用了线程本地缓冲区,我认为这使其成为线程安全的。

https://elixir.bootlin.com/glibc/glibc-2.32/source/string/strsignal.c#L27

那么,从 glibc 2.32 开始,为什么

strerror()
被认为是 MT 安全的,但
strsignal()
仍然是 此处记录为 MT-不安全?

源代码还显示,

strsignal()
没有特定于区域设置的绑定,尽管文档称可能存在区域设置线程竞争。这是未来可能发生的变化的证明吗?

c linux multithreading thread-safety glibc
1个回答
0
投票

首先,您需要认识到 GLIBC 和手册页是完全独立的项目。

文档可能不正确或过时(欢迎补丁)。

其次,

strsignal
使用线程本地缓冲区这一事实本身并不能保证线程安全。所有 strsignal 调用也必须是线程安全的。
“区域设置竞赛”评论意味着

输出受语言环境影响
  • 非线程安全(涉及全局变量)
© www.soinside.com 2019 - 2024. All rights reserved.