ostream 运算符<< in libstdc++ 线程是敌对的吗?
Is ostream operator<< in libstdc++ thread-hostile?
>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 上不会发生。
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- 如何显式调用运算符<<
- 模板操作员&lt;未打电话
- C / CUDA中的模板方法是3个角括号(&lt;&lt;&lt;)
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 错误:调用"std::vector<:vector<int>>::p ush_back(std::vector<std::__cxx11::basic_string<
- C 建造者Clang STD :: Sill,找不到超载的操作员&lt;
- 为什么STD :: MAP需要操作员&lt;以及我如何写一个
- 为什么“操作员”需要const但不是为“运营商&lt;”
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 什么是模板&lt;&gt;inline bla bla
- 左角支架解释为操作员&lt;而不是模板参数
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- 超载操作员&lt;&lt; - 必须是二进制操作员
- 没有匹配的“运营商&lt;&lt;”