【问题标题】:C++ async + future (deferred vs async)C++ 异步 + 未来(延迟与异步)
【发布时间】:2018-08-01 19:15:15
【问题描述】:

这是我正在使用的测试程序。有人可以详细描述发生了什么以及此输出的原因吗?

为什么launch::async 得到g_num 的值为0,而launch::deferred 得到100

launch::asynclaunch::deferred 都在 main 堆栈上得到了正确的 arg 值,我相信这意味着它们应该都得到 100

代码:

#include <iostream>
#include <future>
using namespace std;
    
thread_local int g_num;
    
int read_it(int x) {
    return g_num + x;
}

int main()
{
    g_num = 100;

    int arg = 1;
    future<int> fut = async(launch::deferred, read_it, arg);
    arg = 2;
    future<int> fut2 = async(launch::async, read_it, arg);

    cout << "Defer: " << fut.get() << endl;
    cout << "Async: " << fut2.get() << endl;

    return 0;
}

输出:

Defer: 101
Async: 2

【问题讨论】:

  • 尝试不使用thread_local

标签: c++ multithreading c++11 asynchronous c++14


【解决方案1】:

documentation 声明launch::deferred 将在调用线程上调用函数,而launch::async 将在新线程上调用函数。

对于调用线程,g_num 的值是您在 main 中设置的值。对于新线程,该值是值初始化的(0 用于 int),因为您从未设置它。感谢@MilesBudnek 的更正。

【讨论】:

  • IIRC,全局变量(包括thread_local 的)被初始化值,所以g_num 的值在工作线程中是明确定义的,它只是0
  • @merlin2011 因此,当在下创建新线程时,它是否会查找所有thread_local 变量并将它们设置为默认值,即使在新线程生成之前更改了thread_local 变量?
  • @Seoul:是的。这就是thread_local 限定符for 的含义。每个线程都有自己的完全独立的对象。
【解决方案2】:

g_num 定义为thread_local,这意味着您应用中的每个线程都有自己的g_num 副本

launch::deferred 在调用线程上运行。主线程上的g_num 更改为 100。在使用launch::async 启动的线程上没有更改,这就是它的值仍然是默认值的原因。

【讨论】:

    猜你喜欢
    • 2016-02-02
    • 2019-03-13
    • 1970-01-01
    • 1970-01-01
    • 2018-09-26
    • 2019-01-15
    • 2020-09-02
    • 1970-01-01
    • 2023-03-31
    相关资源
    最近更新 更多