Reputation: 141
In my current code I have a solution that allows the main thread to schedule some job to be asynchronusly executed in the worker thread.
When the worker thread is finished, it is supposed to notify the main thread using the supplied callback function. The main problem is that I want this callback to be executed in the main thread instead of the worker thread, so simple function call from the worker after it finishes its job is not an option (callback performs some application logic that may be quite complex and I don't want the worker thread to be busy with that).
I have a legacy solution for that problem (using events to signal the main thread that the job was completed etc.), but I'm looking for some general and reusable solution - is there anything in C++ that I can use?
Ideally I'm looking for a solution like boost::signals, but as far as I understood that is not thread-aware. Any ideas?
EDIT: final solution must work on linux and be compiled with GCC
EDIT2: some example code added
Typical usage of callbacks may look like this (this won't compile, but I wanted to keep it simple to show the general idea):
///////// main thread ////////////
void fun() { /* work to be done in worker thread */ }
void callback() { /* callback that will be called when fun() is done */ }
int main() {
Worker worker;
worker.doAsync(fun, callback);
// waiting for the worker to finish the job
}
////// worker thread code ///////
/// main worker loop
void Worker::run() {
// wait until the task is scheduled
// run the scheduled tasks
fun();
// when task was finished, call the callback
callback();
}
The problem with the above code is that callback() function will be called from the worker thread - what I want is to have the worker thread signal the main thread that the job is done and the main thread should now call the callback because the job was done.
Upvotes: 2
Views: 2072
Reputation: 725
You can use callback as a wrapper for mainThreadCallback
Create mainThreadCallback
gboolean mainThreadCallback(gpointer data)
{
//cast data to whatever you need
return FALSE; // so it will run only once
}
Inside
void callback()
{
g_idle_add ((GSourceFunc) mainThreadCallback, NULL /* custom data */);
}
The function mainThreadCallback will run in the main thread as soon as it will be available. You will need to have a GMainLoop inside your int main() function.
Upvotes: 0
Reputation: 1047
If your worker is going to return a value, use future
, otherwise, you can just spawn the workers and tell the main thread to wait for them to finish by threadxxx.join()
. Here are two examples:
with thread
s:
#include <thread>
int main()
{
std::thread thread1(fun);
//anything here will be run simultaneously
...
thread1.join();
//anything here will be run after thread1 is done
return 0;
}
with future:
#include <future>
#include <thread>
int main()
{
std::future<double> future1 = std::async(std::launch::async, fun());
//anything here will run simultaneously;
...
//get() will wait for the result, if the thread is not done yet.
double res = future1.get();
//from here on, the task is done
return 0;
}
Upvotes: 0
Reputation: 2164
If you can use C++11, you may have a look at the std::future class. Anyway, you need to wait for the event in the main thread somehow.
std::future<T> f = std::async(std::launch::async, <your_thread_func>);
// do something else
f.wait();
T t = f.get();
Upvotes: 1