123*_*ing 5 c++ multithreading thread-safety c++11
我有这个代码
#include <thread>
typedef struct
{
int a;
short b;
}TestStruct;
void TestParamRef(const TestStruct& test)
{
Sleep(3000); /*Sleep to wait for the caller function end*/
TestStruct i = test; /*Test if the argument's still ok*/
}
void TestParamPointer(TestStruct* test)
{
Sleep(4000); /*Sleep to wait for the caller function end*/
TestStruct i = *test; /*Test if the argument's still ok*/
}
void Test()
{
TestStruct localTest; /*Local variable should be destroyed after this Test function end*/
localTest.a = localTest.b = 69;
std::thread threadRef(TestParamRef, localTest);
threadRef.detach(); /*Bye bye thread*/
localTest.a = 6969;
std::thread threadPointer(TestParamPointer, &localTest);
threadPointer.detach();/*Bye bye thread*/
localTest.b = 696969;
}
int WINAPI _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
Test();
/*Put break point here*/
return 0;
}
Run Code Online (Sandbox Code Playgroud)
正如您在代码中看到的那样,我尝试测试如果将局部变量传递给线程会发生什么,并且在使用它的线程之前销毁此局部变量.我发现TestParamPointer得到一个有趣的值(可能因为它现在指向垃圾值),但TestParamRef仍然得到正确的值.
所以我想知道线程是否真的将其参数存储在自己的内存中?我认为当我使用'const TestStruct&test'时,该函数不会复制整个参数,而是重用那个参数(我在param非常大时使用它 - 就像sql表的数据一样).那么它是如何工作的?将局部变量传递给线程时是否安全.
std :: thread会复制或移动你传递给它的任何参数,所以是的,它是线程安全的.
另一方面,传递原始指针不是线程安全的.事实上,将指针传递给分离线程上的局部变量是非常糟糕的,因为在本地变量超出范围之前不保证线程完成(在线程完成之前,您不使用.join()来阻塞) .稍后当线程开始工作时,它可能会或可能不会有一些工作,这可能会导致崩溃.
http://en.cppreference.com/w/cpp/thread/thread/thread
线程函数的参数按值移动或复制.如果需要将引用参数传递给线程函数,则必须将其包装(例如,使用std :: ref或std :: cref).
此外,如果你使用std :: ref包装引用,通常它会变得不安全,因为它可以从原始上下文访问,所以你需要提供一个同步方法(互斥/锁,线程安全)容器或你有什么).
| 归档时间: |
|
| 查看次数: |
513 次 |
| 最近记录: |