C++並發 練習筆記(二)使用boost Asio的async I/O技術實作簡易網路聊天室 (下)
来源:互联网 发布:哈佛大学知乎 编辑:程序博客网 时间:2024/06/18 17:09
在上一 篇中C++並發 練習筆記(二)使用boost Asio的async I/O技術實作簡易網路聊天室 (上),
我們直接拿開發團隊的範例來做練習、並理解,但關於函數的使用方法及其意義並未太過深入介紹。
這次,我會比較詳細的紀錄並描述下來。
首先先來看一下再Asio當中一個同步的客戶端,是怎麼寫的。
using boost::asio;io_service service;ip::tcp::endpoint ep( ip::address::from_string("127.0.0.1"), 2001);ip::tcp::socket sock(service);sock.connect(ep); service.run();
其中,代碼中一定要創建一個 io_service的這個實體,boost::Asio利用它來跟系統的I/O設備通信,接著再創建
endpoint表示想要連結到的位置以及通訊協定,在此處ip::tcp::endpoint,使用IP協定以及TCP協定進行通信。
再來使用相同通信協定的socket庫來綁定ioservice,並用這個socket來連結到目標端點。
最後的run()函式用於告訴i/o設備開始收發數據。
接著來看一下剛剛同步客戶端跟現在異步客戶端之間的差別
using boost::asio;io_service service;ip::tcp::endpoint ep( ip::address::from_string("127.0.0.1"), 2001);ip::tcp::socket sock(service);sock.async_connect(ep, connect_handler);service.run();void connect_handler(const boost::system::error_code & ec) {// 假如沒有ErrorCode ec,表示成功連線}
跟同步不同的地方在於 socket.connect(endpoint)變成,socket.async_connect(endpoint,回調函數())async_connet()不同於同步的connect(),它永遠立即返回(但不代表執行完成)並繼續執行service.run()這個迴圈並在這裡被阻塞,直到系統消息通知async_connect,
service.run()迴圈將被掛起,並執行該事件的回調函數,完成後將繼續執行迴圈。
一旦確定成功,回調函數(本例中為connect_handler)將會被呼叫,回調函數會接著確認第一要必要項參數 boost::system::error_code
來確保調用是否成功假如成功,則會開始以異步方式向伺服器寫入資料。
io_serviece是Boost.asio中最重要的一個class.他能跟系統內核打交道,並能等待異步函數調用的完成
以下舉例幾個 io_service的使用方式
1.單線程、單一io_service跟一個回調函數線程
io_service service_;//所有socket的操作將會由這個io_service做處理ip::tcp::socketsock1(service_);ip::tcp::socketsock2(service_);sock1.async_connectep,connect_handler);sock2.async_connect(ep,connect_handler);deadline_timer t(serviece_,boost::posix_time::seconds(5));t.async_wait(timeout_handler);//任何一步操作超過五秒將被視為失敗,並會呼叫timeout_handlerservice_.run();
這個是簡單的調用程式,假如有多個回調函數同時發生,則會發生效能瓶頸,並且會變成序列式的呼叫方式
假如說有某個回調函數會花上時間來執行,其他的回調函數將會被阻塞直到它完成。
2.多線程、單一io_service跟多個回調函數線程
io_serviceservice_;ip::tcp::socketsock1(service_);ip::tcp::socketsock2(service_);sock1.async_connect(ep,connect_handler);sock2.async_connect(ep,connect_handler);deadline_time t(service_,boost::posix_time::seconds(5));t.asyc_wait(timeout_handler);for(int i=0;i<5;<<++i)boost::thread(run_serivice);void run_service(){service_.run();}這是大部分開發時真正會使用的方式,此處是創建5個線程來等待兩個異步函數的調用,假如說thread1正在執行回調函數,
service_會自動找尋其他4個空閒中的thread來處理接下來的調用。
3.多線程、多io_service跟多個回調函數線程
io_service service_[2];ip::tcp::socket sock1(service_[0]);ip::tcp::socket sock2(service_[1]);sock1.async_connect( ep, connect_handler);sock2.async_connect( ep, connect_handler);deadline_timer t(service_[0], boost::posix_time::seconds(5));t.async_wait(timeout_handler);for ( int i = 0; i < 2; ++i) boost::thread( boost::bind(run_service, i));void run_service(int idx) { service_[idx].run();}最複雜但最有彈性,當方法二還無法滿足效能上的需求時才會使用這個;連io_serviece管理也多創建出一個實例來。
今天就到這邊吧,預定C++並發編程筆記下一次會記錄有關於boost::asio更多函數的使用方法。
簡單的程式,假如有多個回調函數同時發生,則會發生效能瓶頸,並且會變成序列式的呼叫方式
假如說有某個回調函數會花上時間來執行,其他的回調函數將會被阻塞直到它完成。
- C++並發 練習筆記(二)使用boost Asio的async I/O技術實作簡易網路聊天室 (下)
- C++——boost:asio的使用
- I/O复用的高级应用二:聊天室程序
- Boost下强大的asio
- 客户端应用中的同步I/O boost asio
- 服务端应用中的同步I/O boost asio
- Boost.Asio的使用技巧
- Boost.Asio的使用技巧
- Boost.Asio的使用技巧
- Boost.Asio的使用技巧
- Boost.Asio的使用技巧
- Boost.Asio的使用技巧
- Boost-Asio的使用技巧
- Boost.Asio的使用技巧
- Boost.Asio的使用技巧
- boost asio程序优雅的退出 二
- Boost.Asio(二)
- Boost-asio之二
- 论文笔记《A CNN Regression Approach for Real-Time 2D/3D Registration 》
- unix的grep命令
- F - Dreamoon and WiFi 组合数学
- ununtu 14.04 安卓7.0 编译
- iOS App组件化开发实践
- C++並發 練習筆記(二)使用boost Asio的async I/O技術實作簡易網路聊天室 (下)
- rac重启遭遇ORA-01078、ORA-01565、ORA-17503、ORA-12547
- Spark之中map与flatMap的区别
- qmake之qmake的安装
- Hello World!
- Servlet学习之六cookie的用法
- 性能优化汇总
- yii2框架的模块化使用
- 为什么在父元素标签里子元素的样式不起作用??