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

时间:2017-07-05 12:08:48

标签: c++ multithreading operating-system

例如,我有:

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;
}

1 个答案:

答案 0 :(得分:1)

您的示例代码中有两个独立的事情:将局部变量捕获到lambda函数以及线程及其堆栈的工作方式。

创建lambda函数时捕获局部变量的工作方式相同,无论lambda是在同一个线程还是在不同的线程中。基本上对变量的引用传递给lambda。 有关详细信息,请参阅How are C++11 lambdas represented and passed?

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

将这两个东西放在一起可以使您的示例代码正常工作。

您的代码的第一个版本可能稍微更高效,因为间接级别较低。