原文 http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-
started-with-boostasio/
編譯環境 boost1.59 vs2015
/**************************************************************
技術博客
http://www.cnblogs.com/itdef/
技術交流群
群號碼:324164944
歡迎c c++ windows驅動愛好者 服務器程序員溝通交流
**************************************************************/
A guide to getting started with boost::asio
boost asio 學習指南
boost::asio是一個使用現代C++方法為開發者提供異步模型的跨平台的c++網絡和
底層IO庫.目前已經擁有大量用戶並成為boost庫的一部分
在開始之前,我們將瀏覽下boost::asio綜述。它包括了很多我們必須知道的基本
信息。指南不會涉及整個boost庫的復雜細節,他將指導我們學習如何在我們的程
序中使用ASIO。
本指南不會教授任何編程語言。讀者必須熟悉C++並且熟練使用boost庫,尤其是
ASIO庫。指南也不會教授網絡編程。換句話說,本指南的目標是指導讀者使用
asio,但是依舊需要讀者花費時間讀取官方文檔。
本指南示例是在windows下編譯。如果代碼需要移植,可能需要做一些邏輯上的改
變。所有代碼已經壓縮並上傳,沒有包含工程文件,僅包含源碼文件。代碼依賴
BOOST庫。
1 io_service的基礎
boost::asio的核心對象就是io_service.此對象類似於庫的大腦和心臟。我們使
用一個簡單的示例來熟悉它,調用run成員函數。run函數將阻塞直到所有任務完成
並且沒有任何處理器被分發,或者直到io_service被停止。
代碼示例1a
#include <boost/asio.hpp> #include <iostream> int main( int argc, char * argv[] ) { boost::asio::io_service io_service; io_service.run(); std::cout << "Do you reckon this line displays?" << std::endl; return 0; }
以下示例創建一個work類。work類在有任務運行時通知io_service。換句話說,
當io_service有一個任務對象與其關聯,它將不會停止運行。下個示例驗證這個
說法。
代碼示例1b
#include <boost/asio.hpp> #include <iostream> int main( int argc, char * argv[] ) { boost::asio::io_service io_service; boost::asio::io_service::work work( io_service ); io_service.run(); std::cout << "Do you reckon this line displays?" << std::endl; return 0; }
我們運行示例代碼將得到預期的效果。我們並沒有看到文本的輸出並且程序沒有
退出。在我們熟悉ASIO之后再優化如何優雅退出程序。
下個例子中,我們將簡單的模擬一個循環並且呼叫io_service的poll函數。poll
函數是用來運行io_service對象事件循環處理並執行准備好的處理器。
示例1c
#include <boost/asio.hpp> #include <iostream> int main( int argc, char * argv[] ) { boost::asio::io_service io_service; for( int x = 0; x < 42; ++x ) { io_service.poll(); std::cout << "Counter: " << x << std::endl; } return 0; }
運行這個示例,我們將看見42行的文本輸出並且程序將退出。如果我們有一個指
定給io_service的work對象,是否有不同?
示例1d
#include <boost/asio.hpp> #include <iostream> int main( int argc, char * argv[] ) { boost::asio::io_service io_service; boost::asio::io_service::work work( io_service ); for( int x = 0; x < 42; ++x ) { io_service.poll(); std::cout << "Counter: " << x << std::endl; } return 0; }
運行這個示例,我們獲得之前同樣的輸出。因為poll函數在沒有任務運行時候不
會阻塞。poll函數簡單執行當前任務組並且返回。
選擇poll函數或者run函數取決於函數的設置。這些函數帶來更多的兼容性,程序
員可以更好的調整程序。run函數將阻塞並等待任務,poll函數則不。
如果我們想從io_service移除一個work對象。通過查看文檔,沒有函數提供此種
功能。為了實現此種功能,我們必須使用work對象的智能指針。
示例代碼1e
#include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <iostream> int main( int argc, char * argv[] ) { boost::asio::io_service io_service; boost::shared_ptr< boost::asio::io_service::work > work( new boost::asio::io_service::work( io_service ) ); work.reset(); io_service.run(); std::cout << "Do you reckon this line displays?" << std::endl; return 0; }
程序顯示如何讓從io_service移除work對象,這個功能對於我們優雅的關閉一個掛起的任務很重要。
多線程下呼叫run函數設置執行處理器的線程池。池中等待的線程是同等優先級,io_service隨機選擇一個觸發處理器。
示例代碼1f
#include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <boost/thread.hpp> #include <iostream> boost::asio::io_service io_service; void WorkerThread() { std::cout << "Thread Start\n"; io_service.run(); std::cout << "Thread Finish\n"; } int main( int argc, char * argv[] ) { boost::shared_ptr< boost::asio::io_service::work > work( new boost::asio::io_service::work( io_service ) ); std::cout << "Press [return] to exit." << std::endl; boost::thread_group worker_threads; for( int x = 0; x < 4; ++x ) { worker_threads.create_thread( WorkerThread ); } std::cin.get(); io_service.stop(); worker_threads.join_all(); return 0; }
示例介紹stop成員函數。stop成員函數將發信號給io_service,提示所有任務將停止。所以在當前任務結束后,不再有任務發起。示例中另一個變化就是io_service對象成為全局對象。運行程序后將有4個線程開始傳輸信息,並且在我們敲擊回車后停止。