2011-10-02 95 views
1

我正在使用包裝類來表示網絡連接。我的實現包含一個名爲async_connect()的方法,該方法解析主機/服務並連接到相關端點(如果可能)。事情是這樣的:我應該從resolver :: async_resolve()調用的處理函數調用socket :: connect()嗎?

void tcp::connection::async_connect(std::string const& host, std::string const& service, 
    protocol_type tcp = protocol_type::v4()) 
{ 
    std::cout << "thread [" << boost::this_thread::get_id() << "] tcp::connection::async_connect()" << std::endl; 

    resolver(m_io_service).async_resolve(resolver::query(tcp, host, service), 
     boost::bind(&connection::resolve_handler, this, _1, _2)); 
} 

我想知道,是建立從處理器的連接,通過async_resolve方法完成調用什麼。

我不確定使用主線程或工作線程來調用處理程序。因此,如果我調用socket::connect()(這將是最合理的方式,如果該代碼將從工作線程執行)或再次啓動異步操作(socket::async_connect() - 應在主線程執行時使用該操作)。

void tcp::connection::resolve_handler(boost::system::error_code const& resolve_error, 
    tcp::resolver::iterator endpoint_iterator) 
{ 
    std::cout << "thread [" << boost::this_thread::get_id() << "] tcp::connection::resolve_handler()" << std::endl; 

    if (!resolve_error) 
    { 
     boost::system::error_code ec; 
     m_socket.connect(*endpoint_iterator, ec); 
    } 
} 

我觀察 - 從控制檯輸出 - 我resolve_handler從一個工作線程調用。那麼,在這裏撥打socket::connect()可以嗎?

回答

2

IMO在使用asio時,堅持使用單一編程模型是很好的做法。

你可以自由使用asio的同步(阻塞)調用,你可以調用一些方法(解析,連接等),每個方法都會阻塞直到結果或錯誤可用。

但是,如果您使用的是異步編程模型,那麼您的主線程或調用線程通常會在io_service :: run上被阻塞,並且指定的處理程序將從另一個線程中調用(就像您所描述的那樣)。當使用這種編程模型時,您通常會從處理程序(工作線程)中調用下一個異步方法,因此不必調用socket :: connect,而是調用socket :: async_connect。它看起來像你正在試圖混合兩種不同的模型。我不確定混合這兩個模型(在io_service :: run上阻塞調用線程)以及從處理程序調用同步方法的含義。

+0

哼,處理程序是從工作者線程調用的。那麼,爲什麼我需要排隊另一個操作(通過使用'async_connect')而不是馬上執行它。我認爲這應該是合理的。 – 0xbadf00d

+1

這就是你如何異步使用asio:async_connect是非阻塞版本,這意味着一旦操作(例如連接,讀取等)完成,操作系統會通知你(通過處理程序)。這些操作可能需要任意長的時間,這取決於例如。網絡等。同時,工作者線程可以處理其他操作。這些示例說明了使用asio的不同方法:http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/http/client/sync_client.cpp和http://www.boost。組織/ DOC /庫/ 1_47_0/DOC/HTML/boost_asio /示例/ HTTP /客戶端/ async_client.cpp – Ralf

相關問題