1

I need to wait for multiple asynchronous tasks but I don't want any blocking behavior, so I checked out this answer and I created a non-blocking async algorithm. Here's my code:

std::vector<std::future<int>> asyncs;
for (int i{0}; i < 4; i++) {
  asyncs.push_back(std::async(
    std::launch::async,
    do_something) // do_something() waits for a random amount of ms and returns the time waited
  );
}

for (auto&& fut:asyncs) {
    std::cout << "Wait time: " << fut.get() << std::endl;
}

So when I run it I get the following output:

Wait time: 1544
Wait time: 3350
Wait time: 2915
Wait time: 2775

However, I don't know which order they were started in. Was the async that ran for 1544ms started first or last? Was 2775ms started second or third? Prior to using non-blocking methods, I would

for (int i{0}; i < 4; i++) int value = asyncs[i].get();

This let me know exactly which task had finished because it was that index in the vector. I am coding for speed so I do not want to search the vector every time an async finishes. And I don't want to do anything sloppy like sending the index as a parameter and returning a tuple.

CyanCoding
  • 1,012
  • 1
  • 12
  • 35
  • I usually don't want to be this type of guy, but `std::async` is kind of a mess in C++. I would advise, if you can, using a better framework for asynchronous operations, such as `libunifex` or `asio`. – Guillaume Racicot Nov 23 '21 at 16:44
  • "I don't want to do anything sloppy like sending the index as a parameter and returning a `tuple`" Why? Isn't it a test code anyway? – Sergey Kalinichenko Nov 23 '21 at 16:47
  • @SergeyKalinichenko The example was a test but I'm using this in production with dozens of threads so I would rather have a more clean approach. – CyanCoding Nov 23 '21 at 17:49
  • 1
    @CyanCoding Since returning an index is part of business requirements in production, returning a tuple is not what I would call "sloppy". To make things even better, the compiler will optimize the heck out of it for you, so you wouldn't compromise on the speed either. If you do not particularly like tuples or the syntactic garbage that they inevitably bring (honestly, I cannot blame you for that) you could opt for returning a named `struct`. Optimizations will be done either way, but the second option would be more readable. – Sergey Kalinichenko Nov 23 '21 at 18:21
  • 1
    I don't understand, what about your new approach keeps you from using the old loop with an index? You're still putting the futures into the vector in the same order in which their tasks were started, no? – Wutz Nov 23 '21 at 19:17

0 Answers0