在VS2015中c++局部静态变量初始化线程安全吗?

Is C++ local static variable initialization thread-safe in VS2015

本文关键字:线程 初始化 安全 变量 静态 VS2015 c++ 局部      更新时间:2023-10-16

根据https://msdn.microsoft.com/en-us/library/hh567368.aspx

Magic stats (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2660.htm)在VS2015上支持

但是在调试x64 Vs2015 Update 3中测试以下代码

#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <tchar.h>
#define MAX_THREADS 5
class Sleeper
{
public:
    Sleeper()
    {
        std::cout << "Sleeper n";
        Sleep(100000);
    }
};
DWORD WINAPI MyThreadFunction(LPVOID lpParam)
{
    std::cout << "Sleeper Start" << (int)lpParam << "n";
    static Sleeper s;
    std::cout << "Sleeper Done" << (int)lpParam << "n";
    return 0;
}
int main(int, char**)
{
    DWORD   dwThreadIdArray[MAX_THREADS];
    HANDLE  hThreadArray[MAX_THREADS];
    // Create MAX_THREADS worker threads.
    for (int i = 0; i<MAX_THREADS; i++)
    {
        // Create the thread to begin execution on its own.
        hThreadArray[i] = CreateThread(
            NULL,                   // default security attributes
            0,                      // use default stack size  
            MyThreadFunction,      // thread function name
            (LPVOID)i,               // argument to thread function 
            0,                     // use default creation flags 
            &dwThreadIdArray[i]);   // returns the thread identifier 
                                    // Check the return value for success.
                                    // If CreateThread fails, terminate execution. 
                                    // This will automatically clean up threads and memory. 
        if (hThreadArray[i] == NULL)
        {
            ExitProcess(3);
        }
    } // End of main thread creation loop.
      // Wait until all threads have terminated.
    WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);
    // Close all thread handles and free memory allocations.
    for (int i = 0; i<MAX_THREADS; i++)
    {
        CloseHandle(hThreadArray[i]);
    }
    return 0;
}

给出输出

Sleeper Start0 Sleeper Start2 Sleeper Start3 Sleeper Start1卧铺Start4

这表明初始化静态变量s实际上不是线程安全的

是的。测试结果是错误的。从MyThreadFunction中删除单词sleeper将显示预期的输出

Start1 Sleeper Start4 Start3 Start0 Start2 Done3 Done1 Done0 Done2Done4