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

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

最佳答案

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

创建 lambda 函数时捕获局部变量的方式相同,无论 lambda 是在同一线程还是不同线程中。基本上对变量的引用被传递给 lambda。 参见 How are C++11 lambdas represented and passed?了解更多详情。

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

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

您的代码的第一个版本可能稍微高效一些,因为少了一个间接级别。

关于c++ - 访问其他线程堆栈变量如何在 C++ 中工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44925866/

相关文章:

.net - 添加和删​​除多线程应用程序的事件处理程序

python (操作系统): how to simulate pressing Enter while executing an external application

c++ - 创建一个可以像 Vector of Vectors 一样工作的 C++ 模板类

C++按值从 vector 中删除元素

c++ - 哪些函数是动态调度的?

c++ - 如何将数组推送到标准 vector 中

c# - 使用列表作为线程启动例程的参数时出现索引超出范围错误

c++ - 无法使用 packaged_task 在 thread_group 中创建线程

python - makedirs 给出 OSError : [Errno 13] Permission denied: '/pdf_files'

c - 在C程序中获取系统命令输出