是ostream运算符<<在libstdc ++ thread-hostile?

时间:2014-03-31 04:34:24

标签: c++ thread-safety locale libstdc++

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()

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

由于ostream会影响所有线程,因此在多线程应用程序中调用具有浮点数的<<运算符{{1}}似乎是不安全的,该应用程序将全局区域设置设置为除了&#34; C&#34;。但那会很奇怪,所以我错过了什么?谢谢!

1 个答案:

答案 0 :(得分:4)

最新草案(N3936)特别警告:

§18.10

  

6对setlocale函数的调用可能会引入数据竞争   其他调用setlocale函数或调用函数   受当前C语言环境的影响。实施应该表现出来   好像没有locale :: global()之外的库函数调用   setlocale函数。

更新版本的GCC将呼叫限制为LC_NUMERIC而非LC_ALL,如果您使用glibc&gt; 2.2实现通过调用uselocale来完全避免这个问题,__convert_from_v只修改了当前的线程(我觉得在OSX上用的不多......)。

编辑:我对源代码有了更好的了解

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

唯一可能出现问题的一个问题是,如果使用gnu语言环境模型构建gcc并且glibc是&lt; = 2.2,那么OSX上就不会发生这种情况。