0

This question has been asked before and if I am not wrong, the only way to read the result of a future is either to call get() and block until it is ready or using wait_for() with zero duration as mentioned in the answer - Get the status of a std::future

But, if I just want a worker thread to return me a result that I want it to compute and not wait or block myself for it to complete, can I not just pass it a callback that the worker thread can call when it has computed the result for me? Something like below -

#include <iostream>
#include <thread>
#include <functional>

void foo(std::function<void(int)> callback)
{
    int result = 5;
    callback(result);
}

int main()
{
    int result = 0;
    std::thread worker(foo, [](int result) 
    {
        std::cout << "Result from worker is " << result << std::endl;
    });
    worker.join();
}   

Here, the worker thread would just execute the callback when it has computed the result for me. I don't have to wait for it to finish or block or check in a loop to know when it's ready. Please advice is this is a good approach to be used as currently there is no way to do this without blocking or checking for it in a loop?

Rajeev Mehta
  • 649
  • 9
  • 18

1 Answers1

2

You can certainly create your own thread with a callback, but as soon as you move away from a toy example you will notice that you have potentially created a synchronization problem. This is because your callback is being invoked from a separate thread. So you may want to have the worker thread instead post a message to a queue which you will read later, unless there is no shared state or a mutex is already in place.

In your specific example, let's add one line of code:

int main()
{
    std::thread worker(foo, [](int result) 
    {
        std::cout << "Result from worker is " << result << std::endl;
    });
    std::cout << "I am the main thread" << std::endl; // added
    worker.join();
}

You might think that there are only two possible outputs:

I am the main thread
Result from worker is 5

and

Result from worker is 5
I am the main thread

But in fact there are other possible outputs, such as:

Result from worker is I am the main thread
5

So you have created a bug. You either need synchronization on your shared state (which includes I/O), or you need to orchestrate everything from the main thread (which is what blocking or checking for a future result gives you).

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • "or you need to orchestrate everything from the main thread (which is what blocking or checking for a future result gives you" - This is great, thanks for the clarification :) – Rajeev Mehta Jul 23 '17 at 11:43