Boost ASIO learning (vi) Timers

Source: Internet
Author: User

http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-
Started-with-boostasio?pg=7

6 Timers

Boost::asio provides a Deadline_timer class to provide synchronous and asynchronous interfaces.
The boost documentation provides a good set of examples.
The first example is to create a timer that is 5 seconds apart.

#include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <boost/thread.hpp> #include < boost/thread/mutex.hpp> #include <boost/bind.hpp> #include <iostream>boost::mutex global_stream_lock void Workerthread (boost::shared_ptr< boost::asio::io_service > Io_service) {global_stream_lock.lock (); STD:: cout << "[" << boost::this_thread::get_id () << "] Thread Start" << STD::ENDL;GLOBAL_STREAM_ Lock.unlock (); while (true) {Try{boost::system::error_code ec;io_service->run (EC); if (EC) {GLOBAL_STREAM_ Lock.lock (); Std::cout << "[" << boost::this_thread::get_id () << "] Error:" << EC << Std::en Dl;global_stream_lock.unlock ();} break;} catch (Std::exception & ex) {Global_stream_lock.lock (); Std::cout << "[" << boost::this_thread::get_id ( ) << "] Exception:" << ex.what () << std::endl;global_stream_lock.unlock ();}} Global_stream_lock.lock (); Std::cout << "[" << Boost::this_thread::get_id () << "] Thread Finish" << std::endl;global_stream_lock.unlock ();} void Timerhandler (const Boost::system::error_code & error) {if (error) {global_stream_lock.lock (); Std::cout < < "[" << boost::this_thread::get_id () << "] Error:" << error << STD::ENDL;GLOBAL_STREAM_ Lock.unlock ();} Else{global_stream_lock.lock () std::cout << "[" << boost::this_thread::get_id () << "] Timerhandler" << Std::endl;global_stream_lock.unlock ();}} int main (int argc, char * argv[]) {boost::shared_ptr< boost::asio::io_service > Io_service (New Boost::asio::io_ Service);boost::shared_ptr< boost::asio::io_service::work > work (New Boost::asio::io_service::work (*io_ Service), Global_stream_lock.lock (), Std::cout << "[" << boost::this_thread::get_id () << "] press [ Return] to exit. "<< Std::endl;global_stream_lock.unlock (); boost::thread_group worker_threads;for (int x = 0; x &lt ; 2; ++X) {Worker_threads.create_threaD (Boost::bind (&workerthread, Io_service));} Boost::asio::d eadline_timer timer (*io_service); Timer.expires_from_now (boost::p osix_time::seconds (5)); Timer.async_wait (Timerhandler); Std::cin.get (); Io_service->stop (); Worker_threads.join_all (); return 0;}

  

If we want to create a flush timer. We set the Timer object to global, but may
Causes the shared object to be not thread-safe. Boost::bind can solve this problem. Using Timer objects
shared_ptr pointer, we can use bind and pass the timer to the specified handler, keeping
The timer can be reused.

#include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <boost/thread.hpp> #include < boost/thread/mutex.hpp> #include <boost/bind.hpp> #include <iostream>boost::mutex global_stream_lock void Workerthread (boost::shared_ptr< boost::asio::io_service > Io_service) {global_stream_lock.lock (); STD:: cout << "[" << boost::this_thread::get_id () << "] Thread Start" << STD::ENDL;GLOBAL_STREAM_ Lock.unlock (); while (true) {Try{boost::system::error_code ec;io_service->run (EC); if (EC) {GLOBAL_STREAM_ Lock.lock (); Std::cout << "[" << boost::this_thread::get_id () << "] Error:" << EC << Std::en Dl;global_stream_lock.unlock ();} break;} catch (Std::exception & ex) {Global_stream_lock.lock (); Std::cout << "[" << boost::this_thread::get_id ( ) << "] Exception:" << ex.what () << std::endl;global_stream_lock.unlock ();}} Global_stream_lock.lock (); Std::cout << "[" << Boost::this_thread::get_id () << "] Thread Finish" << std::endl;global_stream_lock.unlock ();} void Timerhandler (const Boost::system::error_code & error,boost::shared_ptr< Boost::asio::d eadline_timer > Timer) {if (error) {global_stream_lock.lock (); Std::cout << "[" << boost::this_thread::get_id () << "] Error: "<< error << Std::endl;global_stream_lock.unlock ();} Else{global_stream_lock.lock () std::cout << "[" << boost::this_thread::get_id () << "] Timerhandler" << Std::endl;global_stream_lock.unlock (); Timer->expires_from_now (boost::p osix_time::seconds (5)); timer- >async_wait (Boost::bind (&timerhandler, _1, Timer));}} int main (int argc, char * argv[]) {boost::shared_ptr< boost::asio::io_service > Io_service (New Boost::asio::io_ Service);boost::shared_ptr< boost::asio::io_service::work > work (New Boost::asio::io_service::work (*io_ Service); Global_stream_lock.lock (); Std::cout << "[" << Boost::this_thread::get_id () << "] press [Return] to exit." << Std::endl;global_stream_lock.unlock (); Boost::thread_group Worker_ threads;for (int x = 0; x < 2; ++x) {Worker_threads.create_thread (Boost::bind (&workerthread, Io_service));} boost::shared_ptr< Boost::asio::d eadline_timer > Timer (new boost::asio::d Eadline_timer (*io_service)); timer- >expires_from_now (boost::p osix_time::seconds (5)); Timer->async_wait (Boost::bind (&timerhandler, _1, timer)); Std::cin.get (); Io_service->stop (); Worker_threads.join_all (); return 0;}

  

There are many interesting things to do with BIND, and the _1 parameter is a placeholder. Because Timerhandler letter
The number requires a parameter for the callback, and we need to reference this bind call. _1 means the first parameter,
We will provide it later.

Running the above example, we will get a timer that is activated every five seconds.
If you want to ensure that the timer does not run at the same time as the work processor, we can use strand.
The code is as follows

#include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <boost/thread.hpp> #include < boost/thread/mutex.hpp> #include <boost/bind.hpp> #include <iostream>boost::mutex global_stream_lock void Workerthread (boost::shared_ptr< boost::asio::io_service > Io_service) {global_stream_lock.lock (); STD:: cout << "[" << boost::this_thread::get_id () << "] Thread Start" << STD::ENDL;GLOBAL_STREAM_ Lock.unlock (); while (true) {Try{boost::system::error_code ec;io_service->run (EC); if (EC) {GLOBAL_STREAM_ Lock.lock (); Std::cout << "[" << boost::this_thread::get_id () << "] Error:" << EC << Std::en Dl;global_stream_lock.unlock ();} break;} catch (Std::exception & ex) {Global_stream_lock.lock (); Std::cout << "[" << boost::this_thread::get_id ( ) << "] Exception:" << ex.what () << std::endl;global_stream_lock.unlock ();}} Global_stream_lock.lock (); Std::cout << "[" << Boost::this_thread::get_id () << "] Thread Finish" << std::endl;global_stream_lock.unlock ();} void Timerhandler (const Boost::system::error_code & error,boost::shared_ptr< Boost::asio::d eadline_timer > timer,boost::shared_ptr< boost::asio::io_service::strand > Strand) {if (error) {global_stream_lock.lock (); STD: : cout << "[" << boost::this_thread::get_id () << "] Error:" << error << Std::endl;global_str Eam_lock.unlock ();} Else{std::cout << "[" << boost::this_thread::get_id () << "] Timerhandler" << std::endl;timer- >expires_from_now (boost::p osix_time::seconds (1)) timer->async_wait (Strand->wrap boost::bind (& Timerhandler, _1, timer, strand)));}} void Printnum (int x) {std::cout << "[" << boost::this_thread::get_id () << "] x:" << x << std: : Endl;boost::this_thread::sleep (Boost::p osix_time::milliseconds (1000));} int main (int argc, char * argv[]) {boost::shared_ptr< boost::asio::io_service > Io_service (new Boost::asio::io_service);boost::shared_ptr< boost::asio::io_service::work > work (New boost:: Asio::io_service::work (*io_service));boost::shared_ptr< boost::asio::io_service::strand > Strand (New boost:: Asio::io_service::strand (*io_service)); Global_stream_lock.lock () std::cout << "[" << Boost::this_ thread::get_id () << "] press [Return] to exit." << Std::endl;global_stream_lock.unlock (); Boost::thread_ Group worker_threads;for (int x = 0; x < 2; ++x) {Worker_threads.create_thread (Boost::bind (&workerthread, Io_ Service));} Boost::this_thread::sleep (boost::p osix_time::seconds (1)); Strand->post (Boost::bind (&printnum, 1)); strand- >post (Boost::bind (&printnum, 2)) Strand->post (Boost::bind (&printnum, 3)); Strand->post (boost:: Bind (&printnum, 4)); Strand->post (Boost::bind (&printnum, 5));boost::shared_ptr< Boost::asio:: Deadline_timer > Timer (new boost::asio::d Eadline_timer (*io_service)); timer->expires_from_now (boost::p osix_time::seconds (1)), timer->async_wait (Strand->wrap (Boost::bind, &timerhandler, Timer, Strand)); Std::cin.get (); Io_service->stop (); Worker_threads.join_all (); return 0;}

  

We need to use the Strand packaged timer processor, strand to ensure that the working object runs after the timer thread first.

In this section we learn how to use bind strand shard_ptr to gain flexibility and implementation capabilities. We will use these components in a later network system.

Boost ASIO learning (vi) Timers

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.