Timer.1 - Using a timer synchronously
This tutorial program introduces asio by showing how to perform a blocking wait on a timer.
这个示例程序通过展示在定时器中执行一个阻塞等待( blocking wait )来介绍Asio。
We start by including the necessary header files.
让我们从必须包含的头文件开始。
All of the asio classes can be used by simply including the "asio.hpp"
header file.
所有的Asio类只要简单的包含"asio.hpp"头文件便可使用。
#include
<
iostream
>
#include
<
boost
/
asio.hpp
>
Since this example users timers, we need to include the appropriate Boost.Date_Time header file for manipulating times.
因为本程序中使用了定时器,我们需要包含相应的的Boost.Date_Time 头文件来处理时间操作。
#include
<
boost
/
date_time
/
posix_time
/
posix_time.hpp
>
All 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 this type first thing in the main function.
使用Asio的所有程序都至少需要一个提供访问I/O功能的boost::asio::io_service对象。因此在主函数中我们做的第一件事就是声明一个这个类型的对象。
int
main()
{
boost::asio::io_service io;
Next we declare an object of type boost::asio::deadline_timer. The core asio classes that provide I/O functionality (or as in this case timer functionality) always take a reference to an io_service as their first constructor argument. The second argument to the constructor sets the timer to expire 5 seconds from now.
接下来我们声明一个boost::asio::deadline_timer类型的对象。作为Asio的核心类,它提供的I/O功能(在此为定时器功能)通常用一个io_service 的引用作为其构造函数的第一个参数。第二个参数设置一个从现在开始5秒后终止的定时器。
boost::asio::deadline_timer t(io, boost::posix_time::seconds(
5
));
In 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 the timer has expired, 5 seconds after it was created (i.e. not from when the wait starts).
在这个简单的程序中,我们用定时器演示一个阻塞等待。boost::asio::deadline_timer::wait()函数调用直到定时器终止(从定时器被创建算起,五秒后终止)才会返回。
A deadline timer is always in one of two states: "expired" or "not expired". If the boost::asio::deadline_timer::wait() function is called on an expired timer, it will return immediately.
一个deadline timer 通常是下面两种状态中的一种:"expired(终止)" 或"not expired(不终止)"。如果boost::asio::deadline_timer::wait()函数被一个已经终止的定时器调用, 它将立即返回。
t.wait();
Finally we print the obligatory "Hello, world!"
message to show when the timer has expired.
最后我们打印出“Hello,world”信息以显示定时器已经终止。
std::cout << " Hello, world! " ;
return 0 ;
}
See the full source listing
查看本例的全部源码:
// timer.cpp
// ~~~~~~~~~
//
// 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 )
//
#include < iostream >
#include < boost / asio.hpp >
#include < boost / date_time / posix_time / posix_time.hpp >
int main()
{
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds( 5 ));
t.wait();
std::cout << " Hello, world! " ;
return 0 ;
}
Timer.2 - Using a timer asynchronously
This tutorial program demonstrates how to use asio's asynchronous callback functionality by modifying the program from tutorial Timer.1 to perform an asynchronous wait on the timer.
这个示例程序示范了如何通过修改Timer.1 中的程序,使用Asio的异步回调功能在定时器中演示一个异步等待。
#include
<
iostream
>
#include
<
boost
/
asio.hpp
>
#include
<
boost
/
date_time
/
posix_time
/
posix_time.hpp
>
Using asio's asynchronous functionality means having a callback function that will be called when an asynchronous operation completes. In this program we define a function called print
to be called when the asynchronous wait finishes.
使用Asio的异步功能意味着当一个异步操作完成时一个回调函数将被调用。在本程序中我们定义一个名为“print”的函数,在异步等待结束后这个函数将被调用。
void
print(
const
boost::system::error_code
&
/*
e
*/
)
{
std::cout
<<
"
Hello, world!
"
;
}
int
main()
{
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(
5
));
Next, instead of doing a blocking wait as in tutorial Timer.1, we call the boost::asio::deadline_timer::async_wait() function to perform an asynchronous wait. When calling this function we pass the print
callback handler that was defined above.
接下来,我们调用boost::asio::deadline_timer::async_wait() 函数执行一个异步等待去取代Timer.1例中的阻塞等待。当调用这个函数时我们传入上面定义的print回调句柄。
t.async_wait(print);
Finally, we must call the boost::asio::io_service::run() member function on the io_service object.
最后,我们必须在io_service对象上调用boost::asio::io_service::run() 成员函数。
The asio library provides a guarantee that callback handlers will only 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 for the asynchronous wait completion will never be invoked.
Asio保证回调句柄仅仅能被boost::asio::io_service::run()启动的当前线程所调用。因此,如果boost::asio::io_service::run() 函数不执行,用于异步等待完成时的回调函数(在本例中为print函数)将永远不会被调用。
The boost::asio::io_service::run() function will also continue to run while there is still "work" to do. In this example, the work is the asynchronous wait on the timer, so the call will not return until the timer has expired and the callback has completed.
当仍旧有“工作”可做时,boost::asio::io_service::run() 函数会继续运行。在本例中,“工作”是定时器的异步等待,因此,直到定时器终止和回调函数执行完成,程序才会返回。
It is important to remember to give the io_service some work to do before calling boost::asio::io_service::run(). For example, if we had omitted the above call to boost::asio::deadline_timer::async_wait(), the io_service would not have had any work to do, and consequently boost::asio::io_service::run() would have returned immediately.
在调用boost::asio::io_service::run()之前确保给io_service 一些工作去做,这非常重要。例如,如果我们省略了上面调用的boost::asio::deadline_timer::async_wait()函数,io_service对象将没有任何事情去做,因此boost::asio::io_service::run() 将立即返回。
io.run();
return 0 ;
}
See the full source listing
查看本例的全部源码:
// timer.cpp
// ~~~~~~~~~
//
// 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 )
//
#include < iostream >
#include < boost / asio.hpp >
#include < boost / date_time / posix_time / posix_time.hpp >
void print( const boost::system::error_code & /* e */ )
{
std::cout << " Hello, world! " ;
}
int main()
{
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds( 5 ));
t.async_wait(print);
io.run();
return 0 ;
}
Timer.3 - Binding arguments to a handler
In this tutorial we will modify the program from tutorial Timer.2 so that the timer fires once a second. This will show how to pass additional parameters to your handler function.
在本示例程序中我们将修改Timer.2中的例子,使定时器每秒被激活一次。例子将示范如何给你的函数指针传递附加参数。
#include
<
iostream
>
#include
<
boost
/
asio.hpp
>
#include
<
boost
/
bind.hpp
>
#include
<
boost
/
date_time
/
posix_time
/
posix_time.hpp
>
To implement a repeating timer using asio you need to change the timer's expiry time in your callback function, and to then start a new asynchronous wait. Obviously this means that the callback function will need to be able to access the timer object. To this end we add two new parameters to the print
function:
- A pointer to a timer object.
- A counter so that we can stop the program when the timer fires for the sixth time.
使用Asio实现一个重复定时器,你必须在你的回调函数中去改变定时器的终止时间,然后开始一个新的异步等待。显然这意味着回调函数必须拥有改变定时器对象的权限。为此我们为print函数增加两个新参数。
一个指向定时器对象的指针
一个用于当定时器第6次被激活时我们可以中止程序的计数器
void
print(
const
boost::system::error_code
&
/*
e
*/
,
boost::asio::deadline_timer
*
t,
int
*
count)
{
As mentioned above, this tutorial program uses a counter to stop running when the timer fires for the sixth time. However you will observe that there is no explicit call to ask the io_service to stop. Recall that in tutorial Timer.2 we learnt that the boost::asio::io_service::run() function completes when there is no more "work" to do. By not starting a new asynchronous wait on the timer when count
reaches 5, the io_service will run out of work and stop running.
如上所示,示例程序使用了一个计数器,当定时器被第6次激活时,用来中止程序。然而,你将看到这里并没有显式地要求io_service对象中止。回忆示例2中,当没有更多“工作”去做时,boost::asio::io_service::run() 函数完成。在计数器达到5时,定时器并没有启动一个新的异步等待。该io_service执行完工作后停止运行。
if ( * count < 5 )
{
std::cout << * count << " " ;
++ ( * count);
Next we move the expiry time for the timer along by one second from the previous expiry time. By calculating the new expiry time relative to the old, we can ensure that the timer does not drift away from the whole-second mark due to any delays in processing the handler.
接着,我们推迟定时器的终止时间。通过在原先的终止时间上增加延时,我们可以确保定时器不会在处理回调函数所需时间内到期。
t -> expires_at(t -> expires_at() + boost::posix_time::seconds( 1 ));
Then we start a new asynchronous wait on the timer. As you can see, the boost::bind() function is used to associate the extra parameters with your callback handler. The boost::asio::deadline_timer::async_wait() function expects a handler function (or function object) with the signature void(const boost::system::error_code&)
. Binding the additional parameters converts your print
function into a function object that matches the signature correctly.
See the Boost.Bind documentation for more information on how to use boost::bind().
In this example, the boost::asio::placeholders::error argument to boost::bind() is a named placeholder for the error object passed to the handler. When initiating the asynchronous operation, and if using boost::bind(), you must specify only the arguments that match the handler's parameter list. In tutorial Timer.4 you will see that this placeholder may be elided if the parameter is not needed by the callback handler.
接着我们在定时器中启动一个新的异步等待。我们必须使用boost::bind() 函数给你的回调函数绑定额外的参数,因为boost::asio::deadline_timer::async_wait() 函数只期望得到一个拥用void(const boost::system::error_code&)签名的函数指针(或函数对象)。为你的print函数绑定附加的参数后,它就成为与签名精确匹配的函数对象。
查看Boost.Bind文档以获得更多如何使用boost::bind()的信息。
在本例中,boost::bind()的boost::asio::placeholders::error参数是为了给回调函数传入一个error对象。当开始异步操作时,如果使用boost::bind(),你必须指定和回调函数的参数列表相匹配的一个参数。在示例4中,如果在回调函数中,这个参数不是必需的,这个占位符会被省略。
t -> async_wait(boost::bind(print,
boost::asio::placeholders::error, t, count));
}
}
int main()
{
boost::asio::io_service io;
A new count
variable is added so that we can stop the program when the timer fires for the sixth time.
为了在定时器第6次被激活时终止程序,我们添加一个新的count变量。
int count = 0 ;
boost::asio::deadline_timer t(io, boost::posix_time::seconds( 1 ));
As in Step 4, when making the call to boost::asio::deadline_timer::async_wait() from main
we bind the additional parameters needed for the print
function.
在第四步中,当在主函数中的调用boost::asio::deadline_timer::async_wait() 函数时,我们绑定print函数所需要的附加参数。
t.async_wait(boost::bind(print,
boost::asio::placeholders::error, & t, & count));
io.run();
Finally, just to prove that the count
variable was being used in the print
handler function, we will print out its new value.
最后,为了证明count变量在print函数句柄中被使用,我们打印出它的值。
std::cout << " Final count is " << count << " " ;
return 0 ;
}
See the full source listing
查看本例的全部源码:
// timer.cpp
// ~~~~~~~~~
//
// 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 )
//
#include < iostream >
#include < boost / asio.hpp >
#include < boost / bind.hpp >
#include < boost / date_time / posix_time / posix_time.hpp >
void print( const boost::system::error_code & /* e */ ,
boost::asio::deadline_timer * t, int * count)
{
if ( * count < 5 )
{
std::cout << * count << " " ;
++ ( * count);
t -> expires_at(t -> expires_at() + boost::posix_time::seconds( 1 ));
t -> async_wait(boost::bind(print,
boost::asio::placeholders::error, t, count));
}
}
int main()
{
boost::asio::io_service io;
int count = 0 ;
boost::asio::deadline_timer t(io, boost::posix_time::seconds( 1 ));
t.async_wait(boost::bind(print,
boost::asio::placeholders::error, & t, & count));
io.run();
std::cout << " Final count is " << count << " " ;
return 0 ;
}
Timer.4 - Using a member function as a handler
In this tutorial we will see how to use a class member function as a callback handler. The program should execute identically to the tutorial program from tutorial Timer.3.
在本例中我们将看到怎样使用类成员函数作为回调句柄。程序完成和Timer.3完全同样的功能。
#include
<
iostream
>
#include
<
boost
/
asio.hpp
>
#include
<
boost
/
bind.hpp
>
#include
<
boost
/
date_time
/
posix_time
/
posix_time.hpp
>
Instead of defining a free function print
as the callback handler, as we did in the earlier tutorial programs, we now define a class called printer
.
我们现在声明一个名为printer的类来取代前个例子程序中的声明的作为回调句柄的自由函数print。
class
printer
{
public
:
The constructor of this class will take a reference to the io_service object and use it when initialising the timer_
member. The counter used to shut down the program is now also a member of the class.
这个类的构造函数使用一个io_service对象的引用来初始化timer_ 成员变量。用来控制关闭程序的计数器现在也是类的一个成员变量。
printer(boost::asio::io_service & io)
: timer_(io, boost::posix_time::seconds( 1 )),
count_( 0 )
{
The boost::bind() function works just as well with class member functions as with free functions. Since all non-static class member functions have an implicit this
parameter, we need to bind this
to the function. As in tutorial Timer.3, boost::bind() converts our callback handler (now a member function) into a function object that can be invoked as though it has the signature void(const boost::system::error_code&)
.
正如自由函数一样,boost::bind() 也可以很好地用在类成员函数上。所有的non-static 成员函量都有一个隐式的this指针参数,我们需要把它绑定到函数上。就像在示例Timer.3中,boost::bind() 使我们的回调函数(现在是一个成员函数)转变成一个签名为void(const boost::system::error_code&)、且可被调用的函数对象。
You will note that the boost::asio::placeholders::error placeholder is not specified here, as the print
member function does not accept an error object as a parameter.
你可能注意到在这里我们并没有指定boost::asio::placeholders::error 占位符,这是因为print成员函数并不接受一个error 对象作为参数。
timer_.async_wait(boost::bind( & printer::print, this ));
}
In the class destructor we will print out the final value of the counter.
在类的析构函数中我们将打印计数器变量的最终值。
~ printer()
{
std::cout << " Final count is " << count_ << " " ;
}
The print
member function is very similar to the print
function from tutorial Timer.3, except that it now operates on the class data members instead of having the timer and counter passed in as parameters.
这个print成员函数同示例Timer.3中的print函数很相似,唯一不同的是它现在操作类的数据成员而不是作为参数传递来的定时器和计数器。
void print()
{
if (count_ < 5 )
{
std::cout << count_ << " " ;
++ count_;
timer_.expires_at(timer_.expires_at() + boost::posix_time::seconds( 1 ));
timer_.async_wait(boost::bind( & printer::print, this ));
}
}
private :
boost::asio::deadline_timer timer_;
int count_;
};
The main
function is much simpler than before, as it now declares a local printer
object before running the io_service as normal.
主函数比前面简单多了。像平常一样运行io_service对象之前,它现在需要声明一个局部的printer对象。
int
main()
{
boost::asio::io_service io;
printer p(io);
io.run();
return
0
;
}
See the full source listing
查看本例的全部源码:
// timer.cpp
// ~~~~~~~~~
//
// 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 )
//
#include < iostream >
#include < boost / asio.hpp >
#include < boost / bind.hpp >
#include < boost / date_time / posix_time / posix_time.hpp >
class printer
{
public :
printer(boost::asio::io_service & io)
: timer_(io, boost::posix_time::seconds( 1 )),
count_( 0 )
{
timer_.async_wait(boost::bind( & printer::print, this ));
}
~ printer()
{
std::cout << " Final count is " << count_ << " " ;
}
void print()
{
if (count_ < 5 )
{
std::cout << count_ << " " ;
++ count_;
timer_.expires_at(timer_.expires_at() + boost::posix_time::seconds( 1 ));
timer_.async_wait(boost::bind( & printer::print, this ));
}
}
private :
boost::asio::deadline_timer timer_;
int count_;
};
int main()
{
boost::asio::io_service io;
printer p(io);
io.run();
return 0 ;
}
Timer.5 - Synchronising handlers in multithreaded programs
This tutorial demonstrates the use of the boost::asio::strand class to synchronise callback handlers in a multithreaded program.
本示例程序示范了使用boost::asio::strand 类来创建多线程程序中的同步回调句柄。
The previous four tutorials avoided the issue of handler synchronisation by calling the boost::asio::io_service::run() function from one thread only. As you already know, the asio library provides a guarantee that callback handlers will only be called from threads that are currently calling boost::asio::io_service::run(). Consequently, calling boost::asio::io_service::run() from only one thread ensures that callback handlers cannot run concurrently.
前四个例程只是在单线程下使用 boost::asio::io_service::run() 函数来避免处理函同步。如你所见,Asio库保证回调句柄仅能被当前正在调用boost::asio::io_service::run()函数的线程调用。因此,在单线程中调用boost::asio::io_service::run()能确保回调句柄不被并发运行。
The single threaded approach is usually the best place to start when developing applications using asio. The downside is the limitations it places on programs, particularly servers, including:
- Poor responsiveness when handlers can take a long time to complete.
- An inability to scale on multiprocessor systems.
单线程通常是使用Asio开发应用程序最好的方式。下面是Asio在程序中的局限性,尤其是服务器方面,包括:
l
操作需要较长时间处理才能完成时弱响应
l
在大规模的多处理机系统中表现不佳
If you find yourself running into these limitations, an alternative approach is to have a pool of threads calling boost::asio::io_service::run(). However, as this allows handlers to execute concurrently, we need a method of synchronisation when handlers might be accessing a shared, thread-unsafe resource.
如果你发现自己陷入这些局限时,一个可供选择的方法是创建一个每个线程都调用boost::asio::io_service::run()的线程池。不过,因为这允许并发操作,当访问一个共享、非线程安全的资源时,我们需要一个同步方式。
#include
<
iostream
>
#include
<
boost
/
asio.hpp
>
#include
<
boost
/
thread.hpp
>
#include
<
boost
/
bind.hpp
>
#include
<
boost
/
date_time
/
posix_time
/
posix_time.hpp
>
We start by defining a class called printer
, similar to the class in the previous tutorial. This class will extend the previous tutorial by running two timers in parallel.
让我们从定义一个名为printer的类开始,这与前一个示例中的类很相似。这个类是上一个例子的扩展,这里我们使用两个并行的定时器。
class
printer
{
public
:
In addition to initialising a pair of boost::asio::deadline_timer members, the constructor initialises the strand_
member, an object of type boost::asio::strand.
An boost::asio::strand guarantees that, for those handlers that are dispatched through it, an executing handler will be allowed to complete before the next one is started. This is guaranteed irrespective of the number of threads that are calling boost::asio::io_service::run(). Of course, the handlers may still execute concurrently with other handlers that were not dispatched through an boost::asio::strand, or were dispatched through a different boost::asio::strand object.
除了初始化一对boost::asio::deadline_timer 成员变量外,构造函数还初始化一个boost::asio::strand类型的strand_成员变量。
boost::asio::strand 对象保证:对于通过它来分派执行的众操作中,只有一个操作执行完成之后才允许进入下一个操作。这种保证与多少个线程调用boost::asio::io_service::run()无关。当然,如果不是通过一个boost::asio::strand对象分派,或者通过其它不同的boost::asio::strand对象分派,这些操作仍旧可能是并发的。
printer(boost::asio::io_service & io)
: strand_(io),
timer1_(io, boost::posix_time::seconds( 1 )),
timer2_(io, boost::posix_time::seconds( 1 )),
count_( 0 )
{
When initiating the asynchronous operations, each callback handler is "wrapped" using the boost::asio::strand object. The boost::asio::strand::wrap() function returns a new handler that automatically dispatches its contained handler through the boost::asio::strand object. By wrapping the handlers using the same boost::asio::strand, we are ensuring that they cannot execute concurrently.
当开始同步操作时,每一个回调句柄都使用boost::asio::strand对象进行“包装”。boost::asio::strand::wrap() 函数返回一个新的通过boost::asio::strand对象自动分派的内部句柄。通过同一boost::asio::strand对象对句柄进行“包装”,我们可以保证操作不会并发执行。
timer1_.async_wait(strand_.wrap(boost::bind( & printer::print1, this )));
timer2_.async_wait(strand_.wrap(boost::bind( & printer::print2, this )));
}
~ printer()
{
std::cout << " Final count is " << count_ << " " ;
}
In a multithreaded program, the handlers for asynchronous operations should be synchronised if they access shared resources. In this tutorial, the shared resources used by the handlers (print1
and print2
) are std::cout
and the count_
data member.
在一个多线程程序中,当访问同一共享资源时,异步操作必须是同步的。在本例中,print1和print2函数使用的共享资源为std::cout 和count_数据成员。
void print1()
{
if (count_ < 10 )
{
std::cout << " Timer 1: " << count_ << " " ;
++ count_;
timer1_.expires_at(timer1_.expires_at() + boost::posix_time::seconds( 1 ));
timer1_.async_wait(strand_.wrap(boost::bind( & printer::print1, this )));
}
}
void print2()
{
if (count_ < 10 )
{
std::cout << " Timer 2: " << count_ << " " ;
++ count_;
timer2_.expires_at(timer2_.expires_at() + boost::posix_time::seconds( 1 ));
timer2_.async_wait(strand_.wrap(boost::bind( & printer::print2, this )));
}
}
private :
boost::asio::strand strand_;
boost::asio::deadline_timer timer1_;
boost::asio::deadline_timer timer2_;
int count_;
};
The main
function now causes boost::asio::io_service::run() to be called from two threads: the main thread and one additional thread. This is accomplished using an boost::thread object.
Just as it would with a call from a single thread, concurrent calls to boost::asio::io_service::run() will continue to execute while there is "work" left to do. The background thread will not exit until all asynchronous operations have completed.
在主函数中,boost::asio::io_service::run() 现在被两个线程调用:主线程和一个附加线程。这一切依赖于boost::thread对象来完成。
正如它被一个单线程调用一样,boost::asio::io_service::run() 的并发调用会一直持续到无任何“工作”可做。后台线程直到所有异步操作都完成后才退出。
int
main()
{
boost::asio::io_service io;
printer p(io);
boost::thread t(boost::bind(
&
boost::asio::io_service::run,
&
io));
io.run();
t.join();
return
0
;
}
See the full source listing
查看本例的全部源码:
//
//
timer.cpp
//
~~~~~~~~~
//
//
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
)
//
#include
<
iostream
>
#include
<
boost
/
asio.hpp
>
#include
<
boost
/
thread.hpp
>
#include
<
boost
/
bind.hpp
>
#include
<
boost
/
date_time
/
posix_time
/
posix_time.hpp
>
class
printer
{
public
:
printer(boost::asio::io_service
&
io)
: strand_(io),
timer1_(io, boost::posix_time::seconds(
1
)),
timer2_(io, boost::posix_time::seconds(
1
)),
count_(
0
)
{
timer1_.async_wait(strand_.wrap(boost::bind(
&
printer::print1,
this
)));
timer2_.async_wait(strand_.wrap(boost::bind(
&
printer::print2,
this
)));
}
~
printer()
{
std::cout
<<
"
Final count is
"
<<
count_
<<
"
"
;
}
void
print1()
{
if
(count_
<
10
)
{
std::cout
<<
"
Timer 1:
"
<<
count_
<<
"
"
;
++
count_;
timer1_.expires_at(timer1_.expires_at()
+
boost::posix_time::seconds(
1
));
timer1_.async_wait(strand_.wrap(boost::bind(
&
printer::print1,
this
)));
}
}
void
print2()
{
if
(count_
<
10
)
{
std::cout
<<
"
Timer 2:
"
<<
count_
<<
"
"
;
++
count_;
timer2_.expires_at(timer2_.expires_at()
+
boost::posix_time::seconds(
1
));
timer2_.async_wait(strand_.wrap(boost::bind(
&
printer::print2,
this
)));
}
}
private
:
boost::asio::strand strand_;
boost::asio::deadline_timer timer1_;
boost::asio::deadline_timer timer2_;
int
count_;
};
int
main()
{
boost::asio::io_service io;
printer p(io);
boost::thread t(boost::bind(
&
boost::asio::io_service::run,
&
io));
io.run();
t.join();
return
0
;
}