[Thread] io_service post is unsuccessful

I'm trying to figure out why a call to boost::io_service::post might be failing. My program is multithreaded, and has a periodic "timing event" that is triggered. The timing event calls "Service.post(&OnSignal);" to execute a handler, while another thread runs the service. Using this design, I can post an event from any thread without worrying about explicit resource locking. My question is, why does my call to Service.post always fail? I know it is failing because the function that I post never gets called. There is not explicit return code or thrown exception to indicate that there is a problem. Below is an example of what I'm trying to do. Inside main(), there is a commented call to "Service.post(&OnSignal);". Uncommenting that line results in a successful post to the Service, which eventually calls OnSignal, (but only once, obviously). Why does that call work, but not the call in TimingSignalThread()? #include <iostream> #include <boost/asio.hpp> #include <boost/thread/thread.hpp> using namespace std; // This is the service responsible for queuing the events. boost::asio::io_service Service; // This is the function that should be periodically queued by the TimingSignalThread. void OnSignal() { cout << "Got timing signal"; } // This function runs in its own thread, and periodically posts OnSignal() to the Service. void TimingSignalThread() { boost::this_thread::disable_interruption di; // Run until interrupted by <enter>. while(!boost::this_thread::interruption_requested()) { cout << "."; boost::this_thread::sleep(boost::posix_time::millisec(500)); Service.post(&OnSignal); // This post is never successful. } } // This function runs in its own thread, and executes all posts. void ServiceRunner() { Service.run(); } int main() { boost::thread TimingThread(&TimingSignalThread); boost::thread ServiceThread(&ServiceRunner); // Why does 'post()' work here, but not in TimingSignalThread()? // Uncommenting the following line results in a single successful post to OnSignal. // Service.post(&OnSignal); cin.get(); // Press enter to end the program. TimingThread.interrupt(); TimingThread.join(); Service.stop(); ServiceThread.join(); cout << "Joined all threads." << endl; return 0; }

Dylan Klomparens wrote:
My question is, why does my call to Service.post always fail? I know it is failing because the function that I post never gets called. There is not explicit return code or thrown exception to indicate that there is a problem.
An io_service keeps running as long as it has work to do. You can force an io_service to keep running by attaching a work object. Try adding boost::asio::io_service::work work(Service); just below main, before the call to Service.run(). Cheers, Rutger

Rutger, I didn't know it would exit when it ran out of work. Your solution worked perfectly! I added that line and Service.run() no longer exits prematurely. Thanks for your insight! -- Dylan For anyone who might try to do something similar in the future, here is the complete code listing that works properly. #include <iostream> #include <boost/asio.hpp> #include <boost/thread/thread.hpp> using namespace std; boost::asio::io_service Service; void OnSignal() { cout << "Got timing signal" << endl; } void TimingSignalThread() { boost::this_thread::disable_interruption di; while(!boost::this_thread::interruption_requested()) { boost::this_thread::sleep(boost::posix_time::millisec(500)); Service.post(&OnSignal); } } void ServiceRunner() { *boost::asio::io_service::work RunForever(Service);* Service.run(); } int main() { boost::thread TimingThread(&TimingSignalThread); boost::thread ServiceThread(&ServiceRunner); cin.get(); TimingThread.interrupt(); TimingThread.join(); Service.stop(); ServiceThread.join(); cout << "Joined all threads." << endl; return 0; } On Wed, Oct 28, 2009 at 4:42 PM, Rutger ter Borg <rutger@terborg.net> wrote:
Dylan Klomparens wrote:
My question is, why does my call to Service.post always fail? I know it is failing because the function that I post never gets called. There is not explicit return code or thrown exception to indicate that there is a problem.
An io_service keeps running as long as it has work to do. You can force an io_service to keep running by attaching a work object. Try adding
boost::asio::io_service::work work(Service);
just below main, before the call to Service.run().
Cheers,
Rutger
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (2)
-
Dylan Klomparens
-
Rutger ter Borg