2014-03-31 45 views
11

ostream运营商<<使用num_put::put()进行数字格式化。我正试图遵守代码。我会链接到OSX文件,但类似的文件出现在我看过的其他系统上。在我看来,那num_put::put()电话num_put::do_put(),要求
num_put::_M_insert_float(),其中calls __convert_from_v()ostream运算符<<在libstdC++ thread-hostile中?

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”别的东西不安全。但那会很奇怪,所以我错过了什么?谢谢!

+0

这可能是OS X上的libstdC++实现有这个问题。我们知道还有其他问题,尤其是许多语言环境功能没有完全实现(它只是在OS X上使用通用语言环境模型)。 libstdC++在OS X上没有得到更新。相反,libC++是未来OS X上的标准C++库实现,您应该尝试使用它。 – bames53

+0

我更新了我的答案,这不是一个问题,因为GCC除了linux以外不支持语言环境。 – user657267

+0

@JonathanWakely很高兴知道。在哪个版本中添加了xlocale支持? (在这个问题中使用的版本是4.2.1,这个版本已经够老,我很确定它没有xlocale支持。) – bames53

回答

4

最新的草案(N3936)明确警告说,不要这样:

§18.10

6 setlocale函数的调用可能会引入数据竞争与其他 调用setlocale函数或调用到 受当前C语言环境影响的函数。该实现应该表现为 ,就好像没有locale :: global()以外的库函数调用 setlocale函数一样。

最近的海湾合作委员会的版本限制呼叫LC_NUMERIC而不是LC_ALL,如果您使用的glibc> 2.2的实现通过调用uselocale只修改当前线程(没多大用了,你在OSX完全避免的问题我猜…)。

编辑:我在源更好看

虽然问题可能与通用语言环境模型发生,如果依赖于C语言环境的函数从另一个线程调用而__convert_from_v或另一个函数修改的C区域设置,通用语言环境模型唯一支持的语言环境是"C"(这是启动期间设置的语言环境),所以这不是问题,除非对通用模型添加了对其他语言环境的支持。

这可能只是一个问题,如果gcc是用gnu语言环境模型构建的,glibc是< = 2.2,这不会在OSX上发生。

相关问题