代码之家  ›  专栏  ›  技术社区  ›  drewpol

std::async未立即调用

  •  1
  • drewpol  · 技术社区  · 6 年前

    我有一些代码示例。我通过了 launch::async async

    #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
    

    get() 被叫来了? 如果我把 sleep_for main thread2 输出是我所期望的。

    3 回复  |  直到 6 年前
        1
  •  4
  •   Pete Becker    6 年前

    对…的呼唤 async 创建 异步 一定是在打电话给 f.get()

        2
  •  0
  •   Lajos Arpad    6 年前

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

    operation1
    asynchronous operation2
    operation3
    

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

        3
  •  0
  •   re_things    6 年前

    试试这个:

    #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); )去了解发生了什么。

    print 函数调用。

    在每一个平台和操作系统中创建线程都是非常困难的任务,它需要花费很多纳秒,而仅仅输出一些更快速的任务。你甚至可以再加10个 调用-它们将比在新线程中打印更快。

    但是 f.get()

    我得到这个代码的输出:

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

    f、 获取() 禁止最后一个呼叫。

    using namespace std; 在这里,但是写 std::