Visual studio 遇到System::Threading::ThreadLocal<;T>;MSVC 2010&;2015 我对VisualStudio如何处理线程本地静态变量的动态初始化感到好奇,所以我决定用C++ + CLI测试它,与普通C++进行比较,使用一对应该具有大致等价行为的简单程序。(启动三个线程,每个线程输出五行,然后让它们在优雅地退出之前全部结束;只要每个线程执行5次thr\u internal(),则与调度无关) < C++程序工作正常: #include <iostream> #include <thread> int _i() { return 0; } void thr_internal() { thread_local int i = _i(); std::cout << "Call: " << i++ << std::endl; } void thr_func(int q) { for (int i = 0; i < 5; i++) { std::cout << "Thread: " << q << "; "; thr_internal(); } } int main() { std::thread t1(thr_func, 1), t2(thr_func, 2), t3(thr_func, 3); t1.join(); t2.join(); t3.join(); }

Visual studio 遇到System::Threading::ThreadLocal<;T>;MSVC 2010&;2015 我对VisualStudio如何处理线程本地静态变量的动态初始化感到好奇,所以我决定用C++ + CLI测试它,与普通C++进行比较,使用一对应该具有大致等价行为的简单程序。(启动三个线程,每个线程输出五行,然后让它们在优雅地退出之前全部结束;只要每个线程执行5次thr\u internal(),则与调度无关) < C++程序工作正常: #include <iostream> #include <thread> int _i() { return 0; } void thr_internal() { thread_local int i = _i(); std::cout << "Call: " << i++ << std::endl; } void thr_func(int q) { for (int i = 0; i < 5; i++) { std::cout << "Thread: " << q << "; "; thr_internal(); } } int main() { std::thread t1(thr_func, 1), t2(thr_func, 2), t3(thr_func, 3); t1.join(); t2.join(); t3.join(); },visual-studio,c++-cli,thread-local-storage,Visual Studio,C++ Cli,Thread Local Storage,但是,如果我为C++/CLI重写程序,打算得到大致相同的代码,使用System::Threading::ThreadLocal #include <iostream> #using <mscorlib.dll> int _i() { return 0; } void thr_internal() { using namespace System::Threading; ThreadLocal<int>^ i = gcnew ThreadL

但是,如果我为C++/CLI重写程序,打算得到大致相同的代码,使用
System::Threading::ThreadLocal

#include <iostream>
#using <mscorlib.dll>

int _i() { return 0; }

void thr_internal() {
    using namespace System::Threading;

    ThreadLocal<int>^ i = gcnew ThreadLocal<int>(_i());

    std::cout << "Call: " << (i->Value)++ << std::endl;
}

void thr_func(System::Object^ q) {
    for (int i = 0; i < 5; i++) {
        std::cout << "Thread: " << safe_cast<int>(q) << "; ";
        thr_internal();
    }
}

int main() {
    using namespace System::Threading;

    Thread^ t1 = gcnew Thread(gcnew ParameterizedThreadStart(&thr_func));
    Thread^ t2 = gcnew Thread(gcnew ParameterizedThreadStart(&thr_func));
    Thread^ t3 = gcnew Thread(gcnew ParameterizedThreadStart(&thr_func));

    t1->Start(1);
    t2->Start(2);
    t3->Start(3);

    t1->Join();
    t2->Join();
    t3->Join();
}
#包括
#使用
int_i(){return 0;}
void thr_internal(){
使用名称空间系统::线程;
ThreadLocal ^i=gcnewthreadlocal(_i());
std::cout Join();
t3->Join();
}
编译器在尝试处理第9行(带有
系统::线程::线程本地
的那一行)时出现动脉瘤。我用MSVC 2010(安装在这台计算机上)和MSVC 2015(通过Rextester)进行了尝试,两者都出现了问题:

VS 2010:

tls_cli.cpp
tls_cli.cpp(9) : fatal error C1001: An internal error has occurred in the compiler.
(compiler file 'msc1.cpp', line 1420)
 To work around this problem, try simplifying or changing the program near the locations listed above.
Please choose the Technical Support command on the Visual C++ 
 Help menu, or open the Technical Support help file for more information
        This diagnostic occurred while importing type 'System::Threading::ThreadLocal::TLSHolder ' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
        tls_cli.cpp(9) : see reference to class generic instantiation 'System::Threading::ThreadLocal<T>' being compiled
        tls_cli.cpp(9) : see reference to class generic instantiation 'System::Threading::ThreadLocal<T>' being compiled
        with
        [
            T=int
        ]
        This diagnostic occurred while importing type 'System::Threading::ThreadLocal::HolderBase ' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
Internal Compiler Error in C:\Program Files\Microsoft Visual Studio 10.0\VC\BIN\cl.exe.  You will be prompted to send an error report to Microsoft later.
tls_cli.cpp
tls_cli.cpp(9):致命错误C1001:编译器中发生内部错误。
(编译器文件'msc1.cpp',第1420行)
要解决此问题,请尝试在上面列出的位置附近简化或更改程序。
请选择Visual C++上的技术支持命令
帮助菜单,或打开技术支持帮助文件以了解更多信息
从程序集“mscorlib,版本=4.0.0.0,区域性=中性,PublicKeyToken=b77a5c561934e089”导入类型“System::Threading::ThreadLocal::TLSHolder”时发生此诊断。
tls_cli.cpp(9):请参阅正在编译的类泛型实例化“System::Threading::ThreadLocal”的参考
tls_cli.cpp(9):请参阅正在编译的类泛型实例化“System::Threading::ThreadLocal”的参考
具有
[
T=int
]
从程序集“mscorlib,版本=4.0.0.0,区域性=中性,PublicKeyToken=b77a5c561934e089”导入类型“System::Threading::ThreadLocal::HolderBase”时发生此诊断。
C:\Program Files\Microsoft Visual Studio 10.0\VC\BIN\cl.exe中出现内部编译器错误。稍后将提示您向Microsoft发送错误报告。
与2015年相比:

source_file.cpp(9): error C3252: 'System::Threading::ThreadLocal::FinalizationHelper::Finalize': cannot reduce accessibility of a virtual method in a managed type
source_file.cpp(9): note: This diagnostic occurred while importing type 'System::Threading::ThreadLocal::FinalizationHelper ' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
source_file.cpp(9): note: see reference to class generic instantiation 'System::Threading::ThreadLocal<T>' being compiled
source_file.cpp(9): note: see reference to class generic instantiation 'System::Threading::ThreadLocal<int>' being compiled
source_file.cpp(9): note: This diagnostic occurred while importing type 'System::Threading::ThreadLocal::LinkedSlotVolatile ' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
source_file.cpp(9):错误C3252:“System::Threading::ThreadLocal::FinalizationHelper::Finalization”:无法减少托管类型中虚拟方法的可访问性
source_file.cpp(9):注意:从程序集“mscorlib,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089”导入类型“System::Threading::ThreadLocal::FinalizationHelper”时发生此诊断。
source_file.cpp(9):注意:请参阅对正在编译的类泛型实例化“System::Threading::ThreadLocal”的引用
source_file.cpp(9):注意:请参阅对正在编译的类泛型实例化“System::Threading::ThreadLocal”的引用
source_file.cpp(9):注意:从程序集“mscorlib,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a561934e089”导入类型“System::Threading::ThreadLocal::LinkedSlotVolatile”时发生此诊断。
我对C++/CLI不太熟悉,因此我怀疑我无意中试图以最糟糕的方式使用
ThreadLocal
,并意外地破坏了它的内部工作,但我无法找到解决错误的方法,也无法通过在线搜索找到任何可能的原因


那么…熟悉C++/CLI的人知道我做错了什么吗?提前感谢。

这是一个很好的描述,我在尝试编写答案时也遇到了一个问题。您尝试使用的ThreadLocal类构造函数需要委托,而不是T。您需要先编写一个ref类,并将ThreadLocal变量设为m“那个类的余烬。@HansPassant好吧,我试过了,但没用。不过我不确定我试过是否正确,而且我在MSDN上找不到任何C++/CLI示例。我试过为int创建一个包装类,并试着将
ThreadLocal
放在包装类中;两者都不起作用。无论我怎么尝试,当我t尝试分配
ThreadLocal
,即使我不传递任何参数,只使用默认构造函数。如果您有一个如何正确创建
ThreadLocal
实例的工作示例,我将不胜感激。@Hanpassant我尝试了
ref struct ThrLoc{static System::Threading::ThreadLocal I;}
,无论是否使用
静态
,都会遇到同样的问题;然后我尝试将其作为
线程本地
的句柄,再次遇到同样的问题。我还尝试了其他一些方法,所有这些都会导致同样的问题。我在Visual Studio 2013中将一些C#代码移植到C++/CLI时也遇到了这个问题。我还没有找到解决方案所以我可能会禁用此功能。这是一个很好的描述,我在尝试编写答案时也遇到了一个问题。您尝试使用的ThreadLocal类构造函数需要委托,而不是T。您需要先编写一个ref类,并使ThreadLocal变量成为该类的成员。@HansPassant好的,我试过了,但是它不起作用。我不确定我是否正确地尝试了它,而且我在MSDN上找不到任何C++/CLI示例。我尝试为int创建一个包装类,并尝试将
ThreadLocal
放在包装类中;两者都不起作用。无论我如何尝试,我在尝试分配
ThreadLocal
时总是会出错,even如果我不传递任何参数,只使用默认构造函数。如果您有一个如何正确创建
ThreadLocal
实例的工作示例,我将不胜感激。@HansPassant我尝试了
ref struct ThrLoc{static System::Threading::ThreadLocal I;};
,无论是否使用
st
source_file.cpp(9): error C3252: 'System::Threading::ThreadLocal::FinalizationHelper::Finalize': cannot reduce accessibility of a virtual method in a managed type
source_file.cpp(9): note: This diagnostic occurred while importing type 'System::Threading::ThreadLocal::FinalizationHelper ' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
source_file.cpp(9): note: see reference to class generic instantiation 'System::Threading::ThreadLocal<T>' being compiled
source_file.cpp(9): note: see reference to class generic instantiation 'System::Threading::ThreadLocal<int>' being compiled
source_file.cpp(9): note: This diagnostic occurred while importing type 'System::Threading::ThreadLocal::LinkedSlotVolatile ' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.