简体   繁体   中英

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

According to https://msdn.microsoft.com/en-us/library/hh567368.aspx

Magic statics ( http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2660.htm ) are supported on VS2015

However testing the following code in debug 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;
}

gives output

Sleeper Start0 Sleeper Sleeper Start2 Sleeper Start3 Sleeper Start1 Sleeper Start4

Which indicates that initializing static variable s is actually not thread safe.

Yes it does. The test was wrong. Removing the word sleeper from MyThreadFunction shows the expected output

Start1 Sleeper Start4 Start3 Start0 Start2 Done3 Done1 Done0 Done2 Done4

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM