访问其他线程堆栈变量如何在C++中工作?

How does access other thread stack variable work in C++?

本文关键字:C++ 工作 其他 线程 堆栈 变量 访问      更新时间:2023-10-16

例如,我有:

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。 请参阅如何表示和传递 C++11 lambda?了解更多详情。

正如 Margaret Bloom 所评论的那样,线程共享进程的地址空间。它们允许读取和修改相同的内存(包括例如全局变量)。虽然每个线程都分配了不同的堆栈区域,但堆栈都在进程的地址空间中,因此所有线程都可以访问其他线程的堆栈区域。因此,如果一个线程有一个指针或对另一个线程堆栈中的变量的引用,它可以读取和修改它。

将这两件事加在一起会使您的示例代码正常工作。

代码的第一个版本可能效率略高,因为间接寻址级别少了一个。