例如,我有:
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;
}
答案 0 :(得分:1)
您的示例代码中有两个独立的事情:将局部变量捕获到lambda函数以及线程及其堆栈的工作方式。
创建lambda函数时捕获局部变量的工作方式相同,无论lambda是在同一个线程还是在不同的线程中。基本上对变量的引用传递给lambda。 有关详细信息,请参阅How are C++11 lambdas represented and passed?。
由Margaret Bloom评论的线程共享进程的地址空间。它们允许读取和修改相同的存储器(包括例如全局变量)。虽然每个线程都分配了不同的堆栈区域,但堆栈都在进程的地址空间中,因此所有线程都可以访问其他线程的堆栈区域。因此,如果一个线程有一个指针或对另一个线程堆栈中的变量的引用,它可以读取和修改它。
将这两个东西放在一起可以使您的示例代码正常工作。
您的代码的第一个版本可能稍微更高效,因为间接级别较低。