未定义的行为,具有setlocale和多线程

Undefined behavior with setlocale and multithreading?

本文关键字:setlocale 多线程 具有 未定义      更新时间:2023-10-16

cppref状态 2016-12-13 09:00 UTC

因为setLocale修改了全局状态,从而影响执行 依赖语言环境的功能,是未定义的行为 一个线程,而另一个线程正在执行以下的任何 功能: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,标准明确指出

呼叫setlocale功能可能会与其他人一起引入数据竞赛 调用setlocale函数或打电话给函数的调用 受当前语言环境的影响。实施的行为应像 没有库功能调用setLocale函数。

所以,不,setlocale不应该是线程安全,除非您的平台提供额外的保证。

由于这是C 通常只是指的是C库的东西,所以我的期望是那里是相同的。

实际上,这意味着在启动任何补充线程之前,您应该仅在多线程程序的启动中使用setlocale