std :: async不会立即被调用

时间:2018-08-18 13:46:01

标签: c++ multithreading asynchronous

我有一些代码示例。我将launch::async传递给async,所以我希望lambda函数将立即被调用,但不会被调用。

#include <iostream>
#include <future>
#include <thread>
#include <vector>
#include <chrono>
#include <string>

using namespace std;

mutex m;

void print(string s)
{
    lock_guard<mutex> l(m);
    cout << s << endl;
}

int main() {
    print("main thread1");

    std::future<int> f = std::async(launch::async, [](){
        print("async");
        return 1;
    });

    print("main thread2");
    int i = f.get();
    print("main thread3");

    return 0;
}

我期望的结果如下:

main thread1
async
main thread2
main thread3

但是实际输出看起来像这样:

main thread1
main thread2
async
main thread3

您能解释为什么只有在调用Future的get()时才调用lambda吗? 如果我将sleep_for放在main thread2之前,那么输出就是我期望的结果。

3 个答案:

答案 0 :(得分:4)

创建新线程后,将立即返回对create or replace view max_per_week as with mx as ( select id, BOOKID, greatest(SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY) max_week from tab) select BOOKID "BookID" , max(max_week) "MaxWeek" from mx group by BOOKID ; var largestNumber = context.max_per_week.Where(s => s.BookID == "B200") .Select(s => new int[] { s.MaxWeek}) 的调用。现在,您有两个单独的线程,并且这两个线程中的操作之间的唯一关联是,对async的调用所创建的线程必须在对async的调用返回之前完成。因此,您看到的行为与要求一致。您期望的行为也符合要求。这就是运行单独的线程的要点:它们独立运行,直到您执行一些操作来同步它们。

答案 1 :(得分:0)

您的期望表明您并不真正理解异步的含义。让我们看一下以下算法:

operation1
asynchronous operation2
operation3

在发出对operation2的异步调用之前,正在执行operation1。异步调用operation2时,将创建一个新线程,并且不等待其结束。如果operation3期望operation2已被执行,则它是代码中的错误。如果需要给定线程的结果,则需要与之同步。

答案 2 :(得分:0)

尝试一下:

#include <iostream>
#include <future>
#include <thread>
#include <vector>
#include <chrono>
#include <string>

using namespace std;
using namespace std::chrono;

mutex m;

void print(string s)
{
    lock_guard<mutex> l(m);
    nanoseconds ms = duration_cast< nanoseconds >(
        system_clock::now().time_since_epoch()
    );
    cout << s << "(" << ms.count() << ")" << endl;
}

int main() {
    print("main thread1");

    future<int> f = async(launch::async, [](){
        print("async");
        return 1;
    });

    //this_thread::sleep_for(2s);
    print("main thread2");
    int i = f.get();
    print("main thread3");

    return 0;
}

尝试尝试睡眠功能(this_thread::sleep_for(2s);),以了解发生了什么事。

如果您想在“主线程2”之前看到“异步”,请在print函数调用之前设置此睡眠。

在每个平台和OS上创建线程都是一项艰巨的任务,花费很多纳秒的时间,而仅输出某些内容则要快得多。因此,您甚至可以再添加10个print调用-它们比在新线程内打印要快。

但是代码中的f.get()迫使系统等待结果。它就像睡眠一样工作。因此,这是在代码示例中最后打印“ main thread3”的唯一原因。

我得到的输出与此代码:

./a.out 
main thread1(1534603161902827214)
main thread2(1534603161902924375)
async(1534603161902977095)
main thread3(1534603161903114658)

“主线程1”和“主线程2”之间的差为97161。 “主线程2”和“主线程3”之间的区别是190283。所有输出都在同一线程中,逐步进行。但是此f.get()禁止最后通话。

另一点。 C ++是一种非常难懂的语言,而学究的语法可以帮助解决代码中的错误。您在此处使用using namespace std;,但无论如何都要编写std::名称空间。这是风格错误。