Is it possible, after calling a boost::thread running some instructions, to come back to main thread ?
My code is based around proactor pattern, however a certain function may take some time, so in order not to block the whole program, I'm creating a thread running this function. When this function is over, I need to call another function, but it has to be run on main thread. I have a connection pool, that is not thread safe, and I really would like to avoid mutex.
Is there a stable way to run a function on the main thread (call on another thread) ?
Just like in ObjectiveC performSelectorOnMaintThread
If you want a function to run in the main thread, you're going to have to implement some type of message-passing system. So for instance, you would launch your main thread, and then launch the worker thread. The worker thread would do it's job, while the main thread would wait for some return value from the worker thread (i.e. the main thread would be checking a message queue or something of that nature). When the worker thread finishes, it will pass into the main thread's message queue a structure (i.e., a message) with a pointer to the function it wants the main thread to run. Your messages can be pretty simple:
struct message
{
typedef void (*func_ptr)(void); //or whatever your function signature would be
func_ptr function;
bool finished;
message(): function(NULL), finished(false) {}
};
So when the worker thread is done, it will create a new message, initialize the function pointer in the message, and push that message back onto the queue that the main thread is waiting on. The main thread then reads the message off the queue, and calls the function.
BTW, and effective way to make the main thread "wait" without having to keep it in a loop and use up CPU cycles would be to use a semaphore or condition variable (like boost::condition
) between the main thread and the worker.
And one more note ... a "message queue" is simply a std::queue<message>
with appropriate locking access that the main thread reads, and the worker thread writes to. There can also be another message queue for the worker thread that the main thread writes to, and the worker thread reads if you need two-way communication between threads.
I think you might want to look into boost asio strands. They will let you specify which thread (strand) to do some wok on, and it will automatically get queued on that strand.
Note that a strand is actually more like a fiber (meaning: if there are more strands than actual threads, the strands will get multiplexed onto the available threads).
IIRC this won't however give you chance to explicitely specify the main thread1. However, more often than not this is not the actual requirement: what strands let you do easily is to make sure that operations in a strand run on the same logical thread, i.e. no concurrency is ever possible within a strand.
Trivia: Boost Asio io_service.run() is an example of a message pump
Here is the samples page for Boost Asio: http://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio/examples.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With