今天在测试boost::asio Tutorial中的 Timer.5 - Synchronising handlers in multithreaded programs 程序时,发现数据处理始终是在主线程中执行的,为了验证“If you find yourself running into these limitations, an alternative approach is to have a pool of threads calling io_service::run()”遂对timer.cpp进行了一些修改:
1.取消使用boost::asio::strand::wrap()来封装回调函数;
2.在printer::print1()中强制线程sleep(1)来检测多线程的并发处理;
完整代码如下:
1 #include < iostream >
2 #include < boost / asio.hpp >
3 #include < boost / thread.hpp >
4 #include < boost / bind.hpp >
5 #include < boost / date_time / posix_time / posix_time.hpp >
6
7 class printer
8 {
9 public :
10 printer(boost::asio::io_service & io)
11 : strand_(io),
12 timer1_(io, boost::posix_time::seconds( 1 )),
13 timer2_(io, boost::posix_time::seconds( 1 )),
14 count_( 0 )
15 {
16 timer1_.async_wait(boost::bind( & printer::print1, this ));
17 timer2_.async_wait(boost::bind( & printer::print2, this ));
18 }
19
20 ~ printer()
21 {
22 std::cout << " Final count is " << count_ << " \n " ;
23 }
24
25 void print1()
26 {
27 std::cout << boost::this_thread::get_id() << " \n " ;
28
29 if (count_ < 10 )
30 {
31 std::cout << " Timer 1: " << count_ << " \n " ;
32 ++ count_;
33
34 timer1_.expires_at(timer1_.expires_at() + boost::posix_time::seconds( 1 ));
35 timer1_.async_wait(boost::bind( & printer::print1, this ));
36 }
37 sleep( 1 );
38 }
39
40 void print2()
41 {
42 std::cout << boost::this_thread::get_id() << " \n " ;
43
44 if (count_ < 10 )
45 {
46 std::cout << " Timer 2: " << count_ << " \n " ;
47 ++ count_;
48
49 timer2_.expires_at(timer2_.expires_at() + boost::posix_time::seconds( 1 ));
50 timer2_.async_wait(boost::bind( & printer::print2, this ));
51 }
52 }
53
54 private :
55 boost::asio::strand strand_;
56 boost::asio::deadline_timer timer1_;
57 boost::asio::deadline_timer timer2_;
58 int count_;
59 };
60
61 int main()
62 {
63 std::cout << boost::this_thread::get_id() << " \n " ;
64
65 boost::asio::io_service io;
66 printer p(io);
67 boost::thread t(boost::bind( & boost::asio::io_service::run, & io));
68 io.run();
69 t.join();
70
71 return 0 ;
72 }
程序运行输出:
0x850e050
0x850e050
Timer 1: 0
0x850e810
Timer 2: 1
0x850e810
Timer 1: 2
0x850e050
Timer 2: 3
0x850e050
Timer 1: 4
0x850e810
Timer 2: 5
0x850e810
Timer 1: 6
0x850e050
Timer 2: 7
0x850e050
Timer 1: 8
0x850e810
Timer 2: 9
0x850e810
0x850e050
从输出结果可以看出:当多个线程运行同一个io_service::run()时,它们将并发执行该io_service上的待处理的handlers!