为什么这个函数级静态变量在 AIX 和 Solaris 中不是线程安全的?

Why is this function-level static variable not thread-safe in AIX and Solaris?

我有这个简单的功能:

bool foo(const std::string& str)
{
    static const std::string ky[] = { "KeyWord1", "KeyWord2", "KeyWord3" };

    static const std::set<std::string> kySet(ky, ky+ sizeof(ky)/sizeof(ky[0]));

    return kySet.find(str) != kySet.end();
}

它基本上包含一组预先设置的关键字,并测试给定的字符串是否是其中一个关键字。

我使用static因为我只想要一份预设变量。

这将 运行 在多线程环境和不同的体系结构上。但是,有人告诉我这仅在 Linux 上是线程安全的,但在 AIX 和 Solaris 上会中断。

我不明白为什么会坏?

只有在编译器不实现 C++ 标准的情况下才会如此。否则 thread-safe 标准保证具有静态存储持续时间的变量的动态初始化,参见 [stmt.dcl]

Dynamic initialization of a block-scope variable with static storage duration or thread storage duration is performed the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration. If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization. [...]

(重点是我的)

引自03标准 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf

第 6.7 节

An implementation is permitted to perform early initialization of other local objects with static storage duration under the same conditions that an implementation is permitted to statically initialize an object with static storage duration in namespace scope (3.6.2). Otherwise such an object is initialized the first time control passes through its declaration; such an object is considered initialized upon the completion of its initialization.

没有提到线程;因此,您应该考虑函数静态不是线程安全的,除非函数是在单线程时调用的。