setlocale 和多线程的未定义行为?
Undefined behavior with setlocale and multithreading?
CppRef states2016-12-13 09:00 UTC:
Because setlocale modifies global state which affects execution of
locale-dependent functions, it is undefined behavior to call it from
one thread, while another thread is executing any of the following
functions: std::fprintf, std::isprint, std::iswdigit,
std::localeconv, std::tolower, std::fscanf, std::ispunct,
std::iswgraph, std::mblen, std::toupper, std::isalnum, std::isspace,
std::iswlower, std::mbstowcs, std::towlower, std::isalpha,
std::isupper, std::iswprint, std::mbtowc, std::towupper, std::isblank,
std::iswalnum, std::iswpunct, std::setlocale, std::wcscoll,
std::iscntrl, std::iswalpha, std::iswspace, std::strcoll, std::wcstod,
std::isdigit, std::iswblank, std::iswupper, std::strerror,
std::wcstombs, std::isgraph, std::iswcntrl, std::iswxdigit,
std::strtod, std::wcsxfrm, std::islower, std::iswctype,
std::isxdigit
.
这个信息似乎......至少令人惊讶。
我知道它会影响全局状态,我没意见(否则我会使用不同的方法来更改语言环境)。
虽然我一直认为(并且我认为 VC++ 至少以这种方式实现)setlocale
与使用语言环境的函数相比是线程安全的。
较新的 C++ 标准(和 C
?)(实际上完全包含线程)对此有任何说明吗?
对于 C11,标准明确规定
A call to the setlocale
function may introduce a data race with other
calls to the setlocale
function or with calls to functions that are
affected by the current locale. The implementation shall behave as if
no library function calls the setlocale function.
所以,不,setlocale
不能认为是线程安全的,除非您的平台做出额外保证。
由于这是 C++ 通常仅引用的 C 库内容,因此我的期望是它在那里是相同的。
实际上,这意味着在启动任何补充线程之前,您应该只在多线程程序的启动中使用 setlocale
。
CppRef states2016-12-13 09:00 UTC:
Because setlocale modifies global state which affects execution of locale-dependent functions, it is undefined behavior to call it from one thread, while another thread is executing any of the following functions:
std::fprintf, std::isprint, std::iswdigit, std::localeconv, std::tolower, std::fscanf, std::ispunct, std::iswgraph, std::mblen, std::toupper, std::isalnum, std::isspace, std::iswlower, std::mbstowcs, std::towlower, std::isalpha, std::isupper, std::iswprint, std::mbtowc, std::towupper, std::isblank, std::iswalnum, std::iswpunct, std::setlocale, std::wcscoll, std::iscntrl, std::iswalpha, std::iswspace, std::strcoll, std::wcstod, std::isdigit, std::iswblank, std::iswupper, std::strerror, std::wcstombs, std::isgraph, std::iswcntrl, std::iswxdigit, std::strtod, std::wcsxfrm, std::islower, std::iswctype, std::isxdigit
.
这个信息似乎......至少令人惊讶。
我知道它会影响全局状态,我没意见(否则我会使用不同的方法来更改语言环境)。
虽然我一直认为(并且我认为 VC++ 至少以这种方式实现)setlocale
与使用语言环境的函数相比是线程安全的。
较新的 C++ 标准(和 C
?)(实际上完全包含线程)对此有任何说明吗?
对于 C11,标准明确规定
A call to the
setlocale
function may introduce a data race with other calls to thesetlocale
function or with calls to functions that are affected by the current locale. The implementation shall behave as if no library function calls the setlocale function.
所以,不,setlocale
不能认为是线程安全的,除非您的平台做出额外保证。
由于这是 C++ 通常仅引用的 C 库内容,因此我的期望是它在那里是相同的。
实际上,这意味着在启动任何补充线程之前,您应该只在多线程程序的启动中使用 setlocale
。