例如,我有:
int main()
{
int i = 0;
std::thread t([&] {
for (int c = 0; c < 100; ++c)
++i;
});
t.join();
return 0;
}
线程t
改变变量i
的值。
我认为,当操作系统更改当前线程时,它必须保存旧线程堆栈并复制新线程堆栈。
操作系统如何提供对i
的访问权?
它是否存在任何解释,它是如何在操作系统级别上工作的?
如果我使用类似这样的东西会不会更有效率:
int main()
{
int* i = new int;
std::thread t([&] {
for (int c = 0; c < 100; ++c)
++(*i);
});
t.join();
return 0;
}
最佳答案
在您的示例代码中有两个不同的事情在起作用:将局部变量捕获到 lambda 函数以及线程及其堆栈的工作方式。
创建 lambda 函数时捕获局部变量的方式相同,无论 lambda 是在同一线程还是不同线程中。基本上对变量的引用被传递给 lambda。 参见 How are C++11 lambdas represented and passed?了解更多详情。
正如 Margaret Bloom 评论的那样,线程共享进程的地址空间。他们授予读取和修改相同内存的权限(包括例如全局变量)。虽然每个线程都有分配给它的不同堆栈区域,但堆栈都在进程的地址空间中,因此所有线程都可以访问其他线程的堆栈区域。因此,如果一个线程有一个指针或对另一个线程堆栈中变量的引用,它可以读取和修改它。
将这两个东西加在一起可以使您的示例代码正常工作。
您的代码的第一个版本可能稍微高效一些,因为少了一个间接级别。
关于c++ - 访问其他线程堆栈变量如何在 C++ 中工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44925866/