象 Boost.Asio 这样的库通常是为了令应用程序具有更高的效率。 应用程序不需要等待特定的函数执行完成,而可以在期间执行其它任务,如开始另一个需要较长时间的操作。

    可扩展性是指,一个应用程序从新增资源有效地获得好处的能力。 如果那些执行时间较长的操作不应该阻塞其它操作的话,那么建议使用 Boost.Asio. 由于现今的PC机通常都具有多核处理器,所以线程的应用可以进一步提高一个基于 Boost.Asio 的应用程序的可扩展性。

    上一节中的例子现在变成了一个多线程的应用。 通过使用在 中定义的 boost::thread 类,它来自于 Boost C++ 库 Thread,我们在 main() 中创建了两个线程。 这两个线程均针对同一个 I/O 服务调用了 方法。 这样当异步操作完成时,这个 I/O 服务就可以使用两个线程去执行句柄函数。

    这个例子中的两个计时数均被设为在五秒后触发。 由于有两个线程,所以 handler1()handler2() 可以同时执行。 如果第二个计时器触发时第一个仍在执行,则第二个句柄就会在第二个线程中执行。 如果第一个计时器的句柄已经终止,则 I/O 服务可以自由选择任一线程。

    要注意,使用线程并不总是值得的。 以上例子的运行会导致不同信息在标准输出流上混合输出,因为这两个句柄可能会并行运行,访问同一个共享资源:标准输出流 std::cout。 这种访问必须被同步,以保证每一条信息在另一个线程可以向标准输出流写出另一条信息之前被完全写出。 在这种情形下使用线程并不能提供多少好处,如果各个独立句柄不能独立地并行运行。

    多次调用同一个 I/O 服务的 方法,是为基于 Boost.Asio 的应用程序增加可扩展性的推荐方法。 另外还有一个不同的方法:不要绑定多个线程到单个 I/O 服务,而是创建多个 I/O 服务。 然后每一个 I/O 服务使用一个线程。 如果 I/O 服务的数量与系统的处理器内核数量相匹配,则异步操作都可以在各自的内核上执行。

    1. #include <boost/asio.hpp>
    2. #include <boost/thread.hpp>
    3. #include <iostream>
    4.  
    5. void handler1(const boost::system::error_code &ec)
    6. {
    7. std::cout << "5 s." << std::endl;
    8. }
    9.  
    10. void handler2(const boost::system::error_code &ec)
    11. {
    12. }
    13.  
    14. boost::asio::io_service io_service1;
    15. boost::asio::io_service io_service2;
    16.  
    17. void run1()
    18. {
    19. io_service1.run();
    20. }
    21.  
    22. void run2()
    23. {
    24. }
    25.  
    26. int main()
    27. {
    28. boost::asio::deadline_timer timer1(io_service1, boost::posix_time::seconds(5));
    29. timer1.async_wait(handler1);
    30. boost::asio::deadline_timer timer2(io_service2, boost::posix_time::seconds(5));
    31. timer2.async_wait(handler2);
    32. boost::thread thread1(run1);
    33. boost::thread thread2(run2);
    34. thread1.join();
    35. thread2.join();

    这个应用程序的功能与前一个相同。 在一定条件下使用多个 I/O 服务是有好处的,每个 I/O 服务有自己的线程,最好是运行在各自的处理器内核上,这样每一个异步操作连同它们的句柄就可以局部化执行。 如果没有远端的数据或函数需要访问,那么每一个 I/O 服务就象一个小的自主应用。 这里的局部和远端是指象高速缓存、内存页这样的资源。 由于在确定优化策略之前需要对底层硬件、操作系统、编译器以及潜在的瓶颈有专门的了解,所以应该仅在清楚这些好处的情况下使用多个 I/O 服务。