Имаме метод, който трябва да бъде извикван често, за да направи някои изчисления (около 20 пъти в секунда). Това е синхронизирано повикване. Обаждащият се трябва да получи резултата възможно най-скоро. Но този процес на изчисление отнема повече време от очакваното понякога. Ние не искаме да променяме нищо друго. Ние просто искаме да добавим вид механизъм за наблюдение, за да маркира приложението текущото изчисление е изтекло, когато надхвърли очаквания период от време.
В момента имаме две възможности:
Вариант 1:
създайте нишка за наблюдение на ниво клас и тя ще продължи да работи през целия живот на приложението. Той ще започне да наблюдава производителността на този изчислителен метод при всяко извикване. Той ще бъде нулиран, когато повикването бъде върнато:
monitorThread.startMonitoring();
doComputation();
monitorThread.stopMonitoring();
Когато се извика startMonitoring(), флагът working
ще бъде зададен на true и началният час ще бъде зададен на текущия час на този monitorThread. ще може да разбере дали текущото състояние е изчакване или не, когато се събуди.
Когато се извика stopMonitoring(), този флаг working
ще бъде зададен на false и monitorThread няма да проверява времето за изчакване.
Вариант 2:
използвайте 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();
Не съм сигурен дали опцията dateline_timer ще работи за нас:
- мога ли да дефинирам таймера на ниво клас и да го използвам повторно по време на цялата работеща сесия на приложението?
- дали това извикване на async_wait() ще доведе до нова нишка във фонов режим? ако да, възможно ли е тази нишка да се използва отново и отново?
РЕДАКТИРАНЕ:
1. Ако използвам следния код в тялото на метод, манипулаторът ще бъде извикан от текущата нишка и doComputation() също се изпълнява в същата нишка. В случай на doComputation() hang, как се извиква обработчикът?
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();
2. За да използвате повторно таймера и да минимизирате броя на нишките. Трябва да инстанцирам io_service в началото, т.е. да поставя boost::asio::deadline_timer timer(io_service);
в конструктора. И също така да извикате io_service.run();
в нова специална тема (и да я оставите да умре след повикването)? или просто да го извикате в основната нишка на init, защото io_service.run() така или иначе ще започне нова нишка? На мястото, където се използва таймерът, е достатъчна следната кодова част:
timer.cancel();
timer.expires_from_now(boost::posix_time::seconds(1));
timer.async_wait(handler);
doComputation(); // <<---- may hung sometime
timer.cancel();
Прав ли съм?