0

How to get send the return data to main thread from the secondary thread in C++

I have a function in a main thread which invokes a function which will process my request in the secondary thread. But the secondary thread will take some time to process the request, so I will breaking my process in the main thread(so, it doesn't lock up the things considering the user can perfrom any other actions which will invoke functions in main thread). Once the process in the secondary thread, how can I send the data to main thread(kind of stuck here).

Any sugesstions will be appreciated.

I tried sending a return to main thread(it was waiting on the same line expecting a return), introduced a set method after the return and get method in another function. I know that's wrong way to do it and I'm locking up the things.

  • At some point you must in your mainthread check if the other thread as finished. Have a look at [std::async/std::future](https://en.cppreference.com/w/cpp/thread/async). If this your mainthread is a (windows) UI thread you may post a message to it upon completion. So any other information you have on your actual situation might help giving a more detailed answer. – Pepijn Kramer May 19 '23 at 08:43
  • `std::async` may take away some freedom of thread management. If you only ever want to communicate back a single result, `std::promise` may be the thing to get the `std::future` from... If you need pass multiple messages, you need to create a queue for storing the products, which you often combine with `std::condition_variable(_any)` for waiting for the next product. As mentioned by Pepijn, GUI libs usually provide a queue for scheduling tasks for execution on the GUI thread which would likely be simpler to use than writing this kind of logic on your own... – fabian May 19 '23 at 08:57

2 Answers2

0

You should pass the arguments in the thread by reference.

void foo(int& res)
{
    std::this_thread::sleep_for(std::chrono::seconds(10));
    res = 8;
}

int main()
{
    int res=0;
    cout<<"res= "<<res<<std::endl;
    std::thread t(foo,std::ref(res));    
    t.join();
    cout<<"res= "<<res<<std::endl;   
    return 0;
}

Output:

res= 0
res= 8

More infos here: Pass multiple arguments into std::thread

Gabriel
  • 3,564
  • 1
  • 27
  • 49
  • Welcome to Stackoverflow. We expect people to post a decent attempt to solve the problem they're asking for help. Since you're a new joiner that's ok for this one, not next one. You will see your question downgraded otherwise. – Gabriel May 19 '23 at 08:54
  • 1
    You might want to look at lambda functions, be careful about passing variables by references to another thread by the time the thread uses them they may have gone out of scope (and no longer exist) – Pepijn Kramer May 19 '23 at 08:59
0

Looks like an use case for std::promise and std::future. A promise is an object that can store a value to be retrieved by a future object (possibly in another thread), offering a synchronization point.

#include <iostream>
#include <thread>
#include <future>

void modifyMessage(std::promise<std::string> && prms, std::string message){
    std::this_thread::sleep_for(std::chrono::milliseconds(4000)); // simulate work
    std::string modifiedMessage = message + " has been modified"; 
    prms.set_value(modifiedMessage);
}

int main(){
    // define message
    std::string messageToThread = "My Message";

    // create promise and future
    std::promise<std::string> prms;
    std::future<std::string> ftr = prms.get_future();

    // start thread and pass promise as argument
    std::thread t(modifyMessage, std::move(prms), messageToThread);

    // print original message to console
    std::cout << "Original message from main(): " << messageToThread << std::endl;

    // retrieve modified message via future and print to console
    std::string messageFromThread = ftr.get();
    std::cout << "Modified message from thread(): " << messageFromThread << std::endl;

    // thread barrier
    t.join();

    return 0;
}

Future's get() member function waits until the future has a valid result and retrieves it. It effectively calls wait() in order to wait for the result. So here it blocks further execution of main until the result is provided by the thread.

YuZ
  • 445
  • 5
  • 18