timer_dox.txt
来自「Boost provides free peer-reviewed portab」· 文本 代码 · 共 381 行
TXT
381 行
//// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)//// Distributed under the Boost Software License, Version 1.0. (See accompanying// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)///**\page tuttimer1 Timer.1 - Using a timer synchronouslyThis tutorial program introduces asio by showing how to perform a blockingwait on a timer.\dontinclude timer1/timer.cpp\skip #includeWe start by including the necessary header files.All of the asio classes can be used by simply including the <tt>"asio.hpp"</tt>header file.\until asio.hppSince this example users timers, we need to include the appropriateBoost.Date_Time header file for manipulating times.\until posix_time.hppAll programs that use asio need to have at least one boost::asio::io_service object.This class provides access to I/O functionality. We declare an object of thistype first thing in the main function.\until boost::asio::io_serviceNext we declare an object of type boost::asio::deadline_timer. The core asio classesthat provide I/O functionality (or as in this case timer functionality) alwaystake a reference to an io_service as their first constructor argument. Thesecond argument to the constructor sets the timer to expire 5 seconds from now.\until boost::asio::deadline_timerIn this simple example we perform a blocking wait on the timer.That is, the call to boost::asio::deadline_timer::wait() will not return until thetimer has expired, 5 seconds after it was created (i.e. <b>not</b> from when thewait starts).A deadline timer is always in one of two states: "expired" or "not expired". Ifthe boost::asio::deadline_timer::wait() function is called on an expired timer, itwill return immediately.\until waitFinally we print the obligatory <tt>"Hello, world!"</tt>message to show when the timer has expired.\until }See the \ref tuttimer1src "full source listing" \nReturn to the \ref index "tutorial index" \nNext: \ref tuttimer2*//**\page tuttimer1src Source listing for Timer.1\include timer1/timer.cppReturn to \ref tuttimer1*//**\page tuttimer2 Timer.2 - Using a timer asynchronouslyThis tutorial program demonstrates how to use asio's asynchronous callbackfunctionality by modifying the program from tutorial Timer.1 to perform anasynchronous wait on the timer.\dontinclude timer2/timer.cpp\skip #include\until posix_time.hppUsing asio's asynchronous functionality means having a callbackfunction that will be called when an asynchronous operation completes. In thisprogram we define a function called <tt>print</tt> to be called when theasynchronous wait finishes.\until boost::asio::deadline_timer Next, instead of doing a blocking wait as in tutorial Timer.1,we call the boost::asio::deadline_timer::async_wait() function to perform anasynchronous wait. When calling this function we pass the <tt>print</tt>callback handler that was defined above.\skipline async_waitFinally, we must call the boost::asio::io_service::run() member functionon the io_service object.The asio library provides a guarantee that callback handlers will <b>only</b>be called from threads that are currently calling boost::asio::io_service::run().Therefore unless the boost::asio::io_service::run() function is called the callback forthe asynchronous wait completion will never be invoked.The boost::asio::io_service::run() function will also continue to run while there isstill "work" to do. In this example, the work is the asynchronous wait on thetimer, so the call will not return until the timer has expired and thecallback has completed.It is important to remember to give the io_service some work to do beforecalling boost::asio::io_service::run(). For example, if we had omitted the above callto boost::asio::deadline_timer::async_wait(), the io_service would not have had anywork to do, and consequently boost::asio::io_service::run() would have returnedimmediately.\skip run\until }See the \ref tuttimer2src "full source listing" \nReturn to the \ref index "tutorial index" \nPrevious: \ref tuttimer1 \nNext: \ref tuttimer3*//**\page tuttimer2src Source listing for Timer.2\include timer2/timer.cppReturn to \ref tuttimer2*//**\page tuttimer3 Timer.3 - Binding arguments to a handlerIn this tutorial we will modify the program from tutorial Timer.2 so that thetimer fires once a second. This will show how to pass additional parameters toyour handler function.\dontinclude timer3/timer.cpp\skip #include\until posix_time.hppTo implement a repeating timer using asio you need to changethe timer's expiry time in your callback function, and to then start a newasynchronous wait. Obviously this means that the callback function will needto be able to access the timer object. To this end we add two new parametersto the <tt>print</tt> function:\li A pointer to a timer object.\li A counter so that we can stop the program when the timer fires for thesixth time.\until {As mentioned above, this tutorial program uses a counter tostop running when the timer fires for the sixth time. However you will observethat there is no explicit call to ask the io_service to stop. Recall that intutorial Timer.2 we learnt that the boost::asio::io_service::run() function completeswhen there is no more "work" to do. By not starting a new asynchronous wait onthe timer when <tt>count</tt> reaches 5, the io_service will run out of work andstop running.\until ++Next we move the expiry time for the timer along by one secondfrom the previous expiry time. By calculating the new expiry time relative tothe old, we can ensure that the timer does not drift away from thewhole-second mark due to any delays in processing the handler.\until expires_atThen we start a new asynchronous wait on the timer. As you cansee, the boost::bind() function is used to associate the extra parameterswith your callback handler. The boost::asio::deadline_timer::async_wait() functionexpects a handler function (or function object) with the signature<tt>void(const boost::system::error_code&)</tt>. Binding the additional parametersconverts your <tt>print</tt> function into a function object that matches thesignature correctly.See the <a href="http://www.boost.org/libs/bind/bind.html">Boost.Binddocumentation</a> for more information on how to use boost::bind().In this example, the boost::asio::placeholders::error argument to boost::bind() is anamed placeholder for the error object passed to the handler. When initiatingthe asynchronous operation, and if using boost::bind(), you must specify onlythe arguments that match the handler's parameter list. In tutorial Timer.4 youwill see that this placeholder may be elided if the parameter is not needed bythe callback handler.\until boost::asio::io_serviceA new <tt>count</tt> variable is added so that we can stop theprogram when the timer fires for the sixth time.\until boost::asio::deadline_timerAs in Step 4, when making the call toboost::asio::deadline_timer::async_wait() from <tt>main</tt> we bind the additionalparameters needed for the <tt>print</tt> function.\until runFinally, just to prove that the <tt>count</tt> variable wasbeing used in the <tt>print</tt> handler function, we will print out its newvalue.\until }See the \ref tuttimer3src "full source listing" \nReturn to the \ref index "tutorial index" \nPrevious: \ref tuttimer2 \nNext: \ref tuttimer4*//**\page tuttimer3src Source listing for Timer.3\include timer3/timer.cppReturn to \ref tuttimer3*//**\page tuttimer4 Timer.4 - Using a member function as a handlerIn this tutorial we will see how to use a class member function as a callbackhandler. The program should execute identically to the tutorial program fromtutorial Timer.3.\dontinclude timer4/timer.cpp\skip #include\until posix_time.hppInstead of defining a free function <tt>print</tt> as thecallback handler, as we did in the earlier tutorial programs, we now define aclass called <tt>printer</tt>.\until publicThe constructor of this class will take a reference to theio_service object and use it when initialising the <tt>timer_</tt> member. Thecounter used to shut down the program is now also a member of the class.\until {The boost::bind() function works just as well with classmember functions as with free functions. Since all non-static class memberfunctions have an implicit <tt>this</tt> parameter, we need to bind<tt>this</tt> to the function. As in tutorial Timer.3, boost::bind()converts our callback handler (now a member function) into a function objectthat can be invoked as though it has the signature <tt>void(constboost::system::error_code&)</tt>.You will note that the boost::asio::placeholders::error placeholder is not specifiedhere, as the <tt>print</tt> member function does not accept an error object asa parameter.\until }In the class destructor we will print out the final value ofthe counter.\until }The <tt>print</tt> member function is very similar to the<tt>print</tt> function from tutorial Timer.3, except that it now operates onthe class data members instead of having the timer and counter passed in asparameters.\until };The <tt>main</tt> function is much simpler than before, as itnow declares a local <tt>printer</tt> object before running the io_service asnormal.\until }See the \ref tuttimer4src "full source listing" \nReturn to the \ref index "tutorial index" \nPrevious: \ref tuttimer3 \nNext: \ref tuttimer5 \n*//**\page tuttimer4src Source listing for Timer.4\include timer4/timer.cppReturn to \ref tuttimer4*//**\page tuttimer5 Timer.5 - Synchronising handlers in multithreaded programsThis tutorial demonstrates the use of the boost::asio::strand class to synchronisecallback handlers in a multithreaded program.The previous four tutorials avoided the issue of handler synchronisation bycalling the boost::asio::io_service::run() function from one thread only. As youalready know, the asio library provides a guarantee that callback handlers will<b>only</b> be called from threads that are currently callingboost::asio::io_service::run(). Consequently, calling boost::asio::io_service::run() fromonly one thread ensures that callback handlers cannot run concurrently.The single threaded approach is usually the best place to start whendeveloping applications using asio. The downside is the limitations it placeson programs, particularly servers, including:<ul><li>Poor responsiveness when handlers can take a long time to complete.</li><li>An inability to scale on multiprocessor systems.</li></ul>If you find yourself running into these limitations, an alternative approachis to have a pool of threads calling boost::asio::io_service::run(). However, as thisallows handlers to execute concurrently, we need a method of synchronisationwhen handlers might be accessing a shared, thread-unsafe resource.\dontinclude timer5/timer.cpp\skip #include\until posix_time.hppWe start by defining a class called <tt>printer</tt>, similarto the class in the previous tutorial. This class will extend the previoustutorial by running two timers in parallel.\until publicIn addition to initialising a pair of boost::asio::deadline_timer members, theconstructor initialises the <tt>strand_</tt> member, an object of typeboost::asio::strand.An boost::asio::strand guarantees that, for those handlers that are dispatched throughit, an executing handler will be allowed to complete before the next one isstarted. This is guaranteed irrespective of the number of threads that arecalling boost::asio::io_service::run(). Of course, the handlers may still executeconcurrently with other handlers that were <b>not</b> dispatched through anboost::asio::strand, or were dispatched through a different boost::asio::strand object.\until {When initiating the asynchronous operations, each callback handler is "wrapped"using the boost::asio::strand object. The boost::asio::strand::wrap() function returns a newhandler that automatically dispatches its contained handler through theboost::asio::strand object. By wrapping the handlers using the same boost::asio::strand, weare ensuring that they cannot execute concurrently.\until }\until }In a multithreaded program, the handlers for asynchronousoperations should be synchronised if they access shared resources. In thistutorial, the shared resources used by the handlers (<tt>print1</tt> and<tt>print2</tt>) are <tt>std::cout</tt> and the <tt>count_</tt> data member.\until };The <tt>main</tt> function now causes boost::asio::io_service::run() tobe called from two threads: the main thread and one additional thread. This isaccomplished using an boost::thread object.Just as it would with a call from a single thread, concurrent calls toboost::asio::io_service::run() will continue to execute while there is "work" left todo. The background thread will not exit until all asynchronous operations havecompleted.\until }See the \ref tuttimer5src "full source listing" \nReturn to the \ref index "tutorial index" \nPrevious: \ref tuttimer4 \n*//**\page tuttimer5src Source listing for Timer.5\include timer5/timer.cppReturn to \ref tuttimer5*/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?