We have a method that needs to be called frequently to do some computations (about 20 times per second). It is a synchronized call. The caller needs to get the result as soon as possible. But that computation process takes longer than expected sometimes. We don't want to change anything else. We just want to add a kind of monitoring mechanism to flag the application the current computation is timeout when it goes over the expected time period.
We have two options right now:
Option 1:
create a monitoring thread in the class level and it will keep running during the entire life of the application. It will start monitor that computation method's performance whenever it is called. It will be reset when the call is returned:
monitorThread.startMonitoring();
doComputation();
monitorThread.stopMonitoring();
When startMonitoring() is called, a working
flag will be set to true and start time will be set to current time on that monitorThread. it will be able to know if the current condition is timeout or not when it wake up.
When stopMonitoring() is called, that working
flag will be set to false and the monitorThread will not check the timeout.
Option 2:
use boost deadline_timer:
boost::asio::deadline_timer timer(io_service);
timer.expires_from_now(boost::posix_time::seconds(1));
timer.async_wait(handler);
doComputation();
timer.cancel();
I am not sure if the dateline_timer option will work for us:
- can I define the timer at class level and reuse it during the entire running session of the application?
- does that async_wait() call will result in a new thread in the background? if yes, is that possible to reuse that thread again and again?
EDIT:
1. If I use the following code within a method body, the handler will be called by the current thread and the doComputation() also runs in the same thread. In the case of doComputation() hang, how the handler is called?
boost::asio::deadline_timer timer(io_service);
timer.expires_from_now(boost::posix_time::seconds(1));
timer.async_wait(handler);
io_service.run(); // new added
doComputation(); // <<---- may hung sometime
timer.cancel();
In order to reuse the timer and minimize the number of thread. I should instantiate io_service at beginning, i.e. put boost::asio::deadline_timer timer(io_service);
in the constructor. And also call io_service.run();
in a new dedicated thread (and let it die after the call)? or just call it in the init main thread because the io_service.run() will start a new thread anyway? In the place the timer is used, the following code piece is enough:
timer.cancel();
timer.expires_from_now(boost::posix_time::seconds(1));
timer.async_wait(handler);
doComputation(); // <<---- may hung sometime
timer.cancel();
Am I right?