ostream 运算符<< in libstdc++ 线程是敌对的吗?

Is ostream operator<< in libstdc++ thread-hostile?

本文关键字:lt 敌对 libstdc++ 运算符 in ostream 线程      更新时间:2023-10-16

>ostream运算符<<使用num_put::put()进行数字格式设置。我正在尝试遵循代码。我将链接到OSX文件,但类似的文件出现在我查看的其他一些系统上。在我看来,num_put::put()num_put::do_put(),它调用
num_put::_M_insert_float(),其中calls __convert_from_v()

http://www.opensource.apple.com/source/libstdcxx/libstdcxx-60/include/c++/4.2.1/bits/c++locale.h
http://www.opensource.apple.com/source/libstdcxx/libstdcxx-60/include/c++/4.2.1/bits/locale_facets.tcc
http://www.opensource.apple.com/source/libstdcxx/libstdcxx-60/include/c++/4.2.1/bits/locale_facets.h

__convert_from_v()检查当前的全局区域设置,如果它与"C"不同,则调用setlocale()将全局区域设置设置为"C",然后使用 vsnprintf() 设置数字格式,然后再次调用setlocale()以恢复到旧的区域设置。

由于setlocale()会影响所有线程ostream,因此在将全局区域设置设置为"C"以外的多线程应用程序中,使用浮点数调用运算符<<似乎是不安全的。但那会很奇怪,所以我错过了什么?谢谢!

最新草案(N3936)特别警告

§ 18.10

6 调用 setlocale 函数可能会引入数据竞争 对 setlocale 函数的其他调用或对以下函数的调用 受当前 C 语言环境的影响。实现应行为 好像除了 locale::global() 之外没有库函数调用 设置区域设置函数。

较新版本的 GCC 将调用限制为 LC_NUMERIC 而不是 LC_ALL ,如果您使用 glibc> 2.2,则实现通过调用仅修改当前线程的 uselocale 完全避免了这个问题(我猜在 OSX 上对你没有多大用处......

编辑:我更好地查看了源代码

尽管如果从另一个线程调用依赖于 C 语言环境的函数,而__convert_from_v或其他函数修改 C 区域设置,则通用区域设置模型可能会出现问题,但通用区域设置模型唯一支持的区域设置是 "C"(这是启动期间设置的区域设置),因此除非将对其他区域设置的支持添加到通用模型中,否则这不是问题。

唯一可能成为问题的情况是,如果 gcc 是使用 gnu 语言环境模型构建的,并且 glibc 是 <= 2.2,这在 OSX 上不会发生。