boost asio 學習(一)io_service的基礎


原文  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個線程開始傳輸信息,並且在我們敲擊回車后停止。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM