简体   繁体   English

为什么调用从异步检索的 future.get() 会导致意外的 output 订单

[英]Why calling future.get() retrieved from async leads to unexpected output order

Consider the following code:考虑以下代码:

#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <future>

std::mutex mutex;

int generate()
{
    static int id = 0;
    std::lock_guard<std::mutex> lock(mutex);
    id++;
    std::cout << id << '\n';
    return id;
}

int main()
{
    std::vector<std::future<int>> vec;
    std::vector<int> result;
    for(int i = 0; i < 10; ++i)
    {
        vec.push_back(std::async(std::launch::async,generate));
    }
    for(int i = 0; i < 10; ++i)
    {
        result.push_back(vec[i].get());
    }
    std::cout << "\n result:";
    for(const auto res : result)
    {
        std::cout << res << " ";
    }
}

Which produces following output:产生以下 output:

1
2
3
4
5
6
7
8
9
10

 result:1 2 3 6 4 5 7 8 9 10

As you can see, the output inside generate() function has correct (from 1 to 10) order.如您所见, generate() function 中的 output 具有正确的(从 1 到 10)顺序。 But when iterating over the result vector I'm getting different order each run.但是当迭代结果向量时,每次运行我都会得到不同的顺序。 Why is this happening and how can I synchronize such code?为什么会发生这种情况,如何同步此类代码?

What you're seeing in the final output is the order in which the threads produced their results.您在最终 output 中看到的是线程产生结果的顺序。

Consider these three threads as a simplified version:将这三个线程视为简化版本:

          +- -+   +- -+    +- -+
Thread    | 1 |   | 2 |    | 3 |
          +- -+   +- -+    +- -+
Result    |   |   |   |    |   |
          +- -+   +- -+    +- -+

Now, no matter which order these execute and acquire the mutex in, the output will be现在,无论这些执行哪个命令并获取互斥锁,output 将是

1 2 3

because id is static , and the first "locker" increments it and prints "1", then the second increments it and prints "2", and so on.因为idstatic ,第一个“储物柜”将其递增并打印“1”,然后第二个将其递增并打印“2”,依此类推。

Let's assume that Thread 3 gets the mutex first, then 1, then 2.让我们假设线程 3 首先获得互斥锁,然后是 1,然后是 2。

That leads to this situation:这导致了这种情况:

          +- -+   +- -+    +- -+
Thread    | 1 |   | 2 |    | 3 |
          +- -+   +- -+    +- -+
Result    | 2 |   | 3 |    | 1 |
          +- -+   +- -+    +- -+

And when you print the results in "vector order", you will see当您以“矢量顺序”打印结果时,您会看到

2 3 1

If you want threads to execute in some predetermined order, you need to synchronize them further.如果您希望线程以某种预定顺序执行,则需要进一步同步它们。

If you resolve the future right away, then it will be in sequence.如果您立即解决未来,那么它将是按顺序排列的。 For example:例如:

#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <future>

std::mutex mutex;

int generate()
{
    static int id = 0;
    std::lock_guard<std::mutex> lock(mutex);
    id++;
    std::cout << id << '\n';
    return id;
}

int main()
{
    std::vector<std::future<int>> vec;
    std::vector<int> result;
    for(int i = 0; i < 10; ++i)
    {
        int result = std::async(std::launch::async,generate).get();
        result.push_back(result);
    }
    std::cout << "\n result:";
    for(const auto res : result)
    {
        std::cout << res << " ";
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM