Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 静态线程安全和初始化顺序_C++_Multithreading_Constructor_Initialization - Fatal编程技术网

C++ 静态线程安全和初始化顺序

C++ 静态线程安全和初始化顺序,c++,multithreading,constructor,initialization,C++,Multithreading,Constructor,Initialization,我在编写的一些代码中遇到了线程问题。 MyStruct在多个线程上构造,这有时会导致程序在staticFunc中崩溃。当代码正在访问一个不安全的变量值(MSVC 2012编译器)时,这让人大吃一惊 我的问题是,解决这个问题的最好方法是什么? 我的第一个想法是一起删除静态声明。 这实际上允许我编写的单元测试通过 struct MyStruct : baseClass { MyStruct() : baseClass(myFunc()) { } int* myFun

我在编写的一些代码中遇到了线程问题。 MyStruct在多个线程上构造,这有时会导致程序在staticFunc中崩溃。当代码正在访问一个不安全的变量值(MSVC 2012编译器)时,这让人大吃一惊

我的问题是,解决这个问题的最好方法是什么? 我的第一个想法是一起删除静态声明。 这实际上允许我编写的单元测试通过

struct MyStruct : baseClass
{
    MyStruct() : baseClass(myFunc())
    {
    }

    int* myFunc()
    {
        this->value = get_array();
        // Do some complex stuff to value.
        return &this->value[0];
    }

    int value[const_size];
};
但我担心的是,如果在构造/初始化之前使用值,这不是未定义的行为吗

施工顺序:

  • 基类构造函数调用myFunc()
  • myFunc()使用值
  • 等等!值尚未由MyStruct的构造函数初始化 这是正在发生的事情还是我遗漏了什么?如果是的话,解决这个问题的正确方法是什么?静态互斥


    编辑:我使用的是MSVC 2012(静态不是线程安全的),不允许移动到其他编译器

    第一个问题是您是想在不同的线程之间共享值,还是每个线程都可以存储自己的值

    如果要跨线程共享该值,则需要使用关键部分保护所有访问


    如果您对持有不同值的不同线程没有问题,则需要查看线程本地存储。c++11为此提供了线程_local,但我不确定MSVC是否支持此功能。否则,您可以使用TlsAlloc、TlsGetValue、TlsSetValue和TlsFree。

    使用
    std::call\u一次
    ,它就是为了解决这个问题而发明的。从内存中,文件范围静态不需要线程安全静态,因为它们必须在输入
    main
    之前初始化,所以在初始化之前,代码中不可能有任何线程

    // Place the func_flag at file scope.
    static std::once_flag my_func_flag;
    class blah {
        static const int* myFunc()
        {
            static int value[const_size];
            std::call_once(my_func_flag, [] {
                // perform ALL mutations of value in here.
                value = get_array();
            });
            // Read-only from here on.
            return &value[0];
        }
    };
    

    c++11
    中,静态也意味着线程安全性,因此一种解决方案是只使用
    c++11
    compiler@bolov还可以将“Dosomecomplementstuff to value”移到一个用于初始化静态变量的函数中。@MikeSeymour是的,我错过了。to OP:原因是静态变量的初始化是线程安全的。如果你初始化然后分配,你就失去了保证。我编辑了我的帖子。我正在使用MSVC 2012,因此静态不是线程安全的。我也没有切换编译器的选项。基类ctor如何调用派生类的方法(在本例中为MyStruct)
    // Place the func_flag at file scope.
    static std::once_flag my_func_flag;
    class blah {
        static const int* myFunc()
        {
            static int value[const_size];
            std::call_once(my_func_flag, [] {
                // perform ALL mutations of value in here.
                value = get_array();
            });
            // Read-only from here on.
            return &value[0];
        }
    };