boost主页asio指南的第二个例子:异步定时器的使用
程序运行结果:
Hello,error!
Hello,world!
因为定时器在3秒的时候被取消,该任务调用结果视为错误,并作为参数返回给回调函数。
---为什么要调用io_service::run()?
asio库提供这样的保证:只有现在调用io_service::run()的线程才能调用回调函数句柄,因此,如果io_services::run()函数不被调用,异步wait将永远不会被唤醒。
只要仍然有“工作”未完成,io_service::run()就会继续执行下去。在本例中,“工作”指的就是在定时器上的异步wait,所以除非所定时长过完,回调结束,run就不会返回。
重要的是,一定要记得在调用io_service::run()之前给io_sevice一些事情做,如果我们省略之前对deadline_timer::asyn_wait()的调用,io_service没有任何事情可做,那么io_service::run()就会立刻返回。
第五个例子,多线程异步计时器的使用
代码见http://www.boost.org/doc/libs/1_43_0/doc/html/boost_asio/tutorial/tuttimer5.html
倘若把其中的strand对象的wrap()函数去掉,则代码如下:
这种情况下,在count=6时,会出现timer1和timer2同时计数的情况。查看线程编号可以看到,此时两个timer的线程编号不同。处于不同的线程中,因此会发生同时修改count值的情况。
注:这是一般情况,很有可能在线程运行的时候会受到多方面因素的影响,例如CPU正忙,进程被暂停,或者io_service中有耗时的操作,定时器可能不能被及时触发,那么也可能不会发生同时计数的情况。
而在没有删除wrap()函数的时候,运行多次的结果显示,timer1和timer2处于同一个线程中。
据此我们可以推论,wrap()函数采用了一定的方式,强制使两个timer处于同一个线程中执行,使它们能够保证有序执行,而不会发生同时执行的现象。