Mic*_*rst 20 c++ memory heap stack multithreading
我是C++新线程的新手,我试图清楚地了解线程之间如何共享/不共享内存.我正在使用std::threadC++ 11.从我在其他SO问题上看到的,堆栈内存只由一个线程拥有,堆内存在线程之间共享.所以从我认为我对堆栈与堆的理解,以下内容应该是正确的:
#include <thread>
using namespace std;
class Obj {
public:
int x;
Obj(){x = 0;}
};
int main() {
Obj stackObj;
Obj *heapObj = new Obj();
thread t([&]{
stackObj.x++;
heapObj->x++;
});
t.join();
assert(heapObj->x == 1);
assert(stackObj.x == 0);
}
Run Code Online (Sandbox Code Playgroud)
请原谅我,如果我搞砸了一堆东西,lambda语法对我来说是非常新的.但希望我正在努力做的是连贯的.这会像我期望的那样表现吗?如果没有,我有什么误解?
Jam*_*lis 28
记忆是记忆.C++中的对象占用内存中的某个位置; 该位置可能位于堆栈上或堆上,也可能已静态分配.对象的位置无关紧要:任何具有引用或指向对象的指针的线程都可以访问该对象.如果两个线程有一个引用或指向该对象的指针,则两个线程都可以访问它.
在您的程序中,您创建一个工作线程(通过构造一个std::thread)来执行您提供的lambda表达式.因为您捕获了两者stackObj并heapObj通过引用(使用[&]捕获默认值),所以lambda引用了这两个对象.
这些对象都位于主线程的堆栈上(注意,它heapObj是一个指针类型对象,位于主线程的堆栈上,指向位于堆上的动态分配对象).没有制作这些物品的副本; 相反,您的lambda表达式具有对象的引用.它stackObj直接修改并修改heapObj间接指向的对象.
主线程后加入与工作线程,都heapObj->x和stackObj.x具有的价值1.
如果您已经使用了价值获取默认的([=]),您的lambda表达式会复制都stackObj和heapObj.stackObj.x++lambda 表达式中的表达式将增加副本,并且stackObj您声明的表达式将main()保持不变.
如果捕获heapObjby值,则只复制指针本身,因此在使用指针的副本时,它仍然指向同一个动态分配的对象.该表达式heapObj->x++将取消引用该指针,从而产生Obj您创建的new Obj(),并增加其值.然后你会在结束时观察main()到heapObj->x它已经增加了.
(注意,为了修改由value捕获的对象,必须声明lambda表达式mutable.)