Reputation: 6343
I have used std::async
for speeding up the execution of a task, which was previously being executed sequentially.
My implementation does the following:
Though this works fine, it is possible that any of the 10 tasks could complete first. My implementation always waits on the first task in the vector. Is there a way to know, which of the 10 tasks completed first?
For e.g. future object itself signalling that it is ready.
I want to achieve functionality similar to "WhenAny()" function mentioned in this article: https://msdn.microsoft.com/en-us/library/jj155756.aspx
Upvotes: 0
Views: 664
Reputation: 275280
Use a thread pool. Queue all of your tasks. Have them report to an atomic counter when done, and have them signal a condition variable when the counter says all are done.
Thread pool implementations abound on stack overflow and elsewhere.
I find using C++11 threading primitives directly in client code is questionable; using them to write little helpers is a better idea.
Upvotes: 1
Reputation: 36
I think that the equivalent to WhenAny (C#) has not yet been incorporated in the C++11/14 standard, thought it is being considered as an experimental future extension (see this). I think latests versions of Boost libraries include when_any, check this out. This company sells also a complete thread library that includes when_any.
Upvotes: 1
Reputation: 1827
Give them each an ID and use an atomic to store the first that finishes.
Somewhere in scope of all of the functions:
std::atomic<int> first_id(0);
At the completion of each task:
first_id.compare_exchange_strong(0, id);
Where id
is from 1 to 10. It will only run once and the first one to run this will be the one to replace the 0.
Edit: The above is the answer to your literal question. But it doesn't really help you do what you want. To do what you want, I'd change the vector to a queue and have each task enqueue the next when it exits (you'll also need a lock to lock the queue before modifying it.) Alternatively, you could use a threadpool. (Shameless plug: here's mine.) A thread pool would let you enqueue all the tasks, but only use n
threads, which will prevent overtaxing the scheduler while still making the coding simple.
Upvotes: 1