boost async_wait() ще предизвика нова нишка?

Имаме метод, който трябва да бъде извикван често, за да направи някои изчисления (около 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 ще работи за нас:

  1. мога ли да дефинирам таймера на ниво клас и да го използвам повторно по време на цялата работеща сесия на приложението?
  2. дали това извикване на 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();

Прав ли съм?


person 5YrsLaterDBA    schedule 09.06.2014    source източник


Отговори (1)


мога ли да дефинирам таймера на ниво клас и да го използвам повторно по време на цялата работеща сесия на приложението?

Да, можете да използвате отново таймера, т.е. ="nofollow">expires_from_now() и async_wait() отново (но прочетете препратката, за да разберете тяхното поведение!).

дали това извикване на async_wait() ще доведе до нова нишка във фонов режим? ако да, възможно ли е тази нишка да се използва отново и отново?

Не (но във всеки случай това е детайл от изпълнението). handler ще бъде извикан от нишката, изпълняваща io_service::run().

След вашето РЕДАКТИРАНЕ:

  1. Силно препоръчително е да разгледате документацията на Asio . Имайте предвид, че io_service::run() е блокиращо повикване - блокира, докато не бъдат извикани всички манипулатори за завършване. Можете да мислите за това като за "цикъл на съобщенията". Обикновено човек го извиква от специална тема. Като алтернатива човек може да анкетира io_service ръчно, като извика poll()/poll_one() в друг специфичен за приложението цикъл.

  2. io_service::run() се връща, когато няма повече работа, т.е. няма чакащи асинхронни операции и манипулатори за завършване за изпращане. За да поддържате този „цикъл със съобщения“ работещ през целия живот на вашия модул (така че да можете да издавате асинхронни операции, когато пожелаете), трябва да асоциирайте io_service::work обект с io_service.

person Igor R.    schedule 09.06.2014
comment
Това означава, че трябва да извикам io_service::run(), което ще задейства нова нишка всеки път? - person 5YrsLaterDBA; 10.06.2014
comment
@5YrsLaterDBA Защо нова тема всеки път? Обикновено се изпълнява io_service::run() в нишка за целия живот на приложението (или модула). След това можете да използвате този io_service за произволен брой Asio обекти (таймери, гнезда и т.н.). - person Igor R.; 10.06.2014
comment
може ли да ми помогнете повече? Добавих още в горния раздел РЕДАКТИРАНЕ. Все още съм малко объркан относно това как работи таймерът. - person 5YrsLaterDBA; 10.06.2014
comment
@5YrsLaterDBA Актуализирах отговора, но моля, преминете през основния урок за Asio и погледнете общ преглед. - person Igor R.; 10.06.2014