我已经读过不同的线程共享除堆栈之外的相同内存段。有一些我一直试图理解的东西。我有一个创建不同线程的类。下面是我正在做的一个简单示例,在构造函数中创建一个线程。
当创建此类的对象时,例如,在main()中,所有线程都可以访问相同的成员变量。如果每个线程都有自己的堆栈,为什么每个线程都不会获得成员变量的副本而不是访问同一个变量。我环顾四周,试图用不同的堆栈框架在脑海中想象一下内存中发生的事情。非常感谢任何回复。
////////////////////////
MyClass::MyClass()
{
t1 = std::thread([this] { this->threadFunc(); });
t1.detach();
}
/////////////////////////
void MyClass::threadFunc()
{
///do stuff.. update member variables etc.
}
答案 0 :(得分:3)
我已经读过不同的线程分享相同的内存段 从堆栈。
这不完全准确。线程共享相同的地址空间,而不像进程一样是沙盒子。
堆栈只是应用程序中的一些内存,它是专门保留的,用于保存函数参数,局部变量和其他与函数相关的信息。
每个线程都拥有自己的堆栈。这意味着当一个特定的线程正在执行时,它将使用它自己的特定堆栈来避免践踏可能在多核系统中空闲或同时执行的其他线程。
请记住,这些堆栈仍然在相同的地址空间内,这意味着任何线程都可以访问其他线程的内容。叠加。
一个简单的例子:
call "C:\example file.exe"
插图:
正如您所看到的,每个线程都有自己的堆栈(这只是进程和内存的一部分),它们位于同一个地址空间内。
答案 1 :(得分:1)
如果你有
MyClass c1;
MyClass c2;
然后会有两个MyClass,c1和c2实例,每个实例都有自己的成员。在构建c1期间启动的线程只能访问c1的成员,而在c2中启动的线程只能访问c2的成员。
如果你在谈论一个类中的几个线程(从你的代码中不明显),那么每个线程都有this
的副本,它只是指向你的MyClass对象的指针。新的(本地)变量将在线程的堆栈上分配,并且只对创建它们的线程可见。
答案 2 :(得分:0)
我已经读过不同的线程共享除堆栈之外的相同内存段。 [...]如果每个线程都有自己的堆栈,为什么每个线程都不会获得成员变量的副本而不是访问同一个变量。
嗯...简短的回答是,这就是设计线程的目的:多个执行线程,所有线程都访问相同的数据。然后你有线程原语 - 比如互斥体 - 以确保它们不会踩到彼此的脚趾,可以说 - 例如,你没有并发写入。
因此,在默认情况下,线程共享对象,您必须做额外的工作来同步访问。如果你想让每个线程都有对象的副本......那么你可以编写代码来给每个线程一个对象的副本,而不是同一个对象。或者,您可以考虑使用流程(例如,通过fork()
)而不是线程。