![](/img/trans.png)
[英]How to catch boost asio boost::system::error_code connect exception separatly from other exceptions?
[英]boost::system::error_code::message() throwing access violation exception with boost::asio socket
我正在實現一個客戶端應用程序,它必須與硬件設備建立少量套接字連接。 我已將問題分解為以下小代碼子集
boost::system::error_code ec;
std::string str_message = ec.message(); // no access violation before connect()
std::string str_port = "502";
std::string str_ip = "192.168.12.198";
boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(),str_ip,str_port);
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
boost::asio::ip::tcp::socket s(io_service);
ec = s.connect(*iterator,ec);
if (ec)
{
// connection error of some kind.
std::string str_debug = ec.message(); // BANG!!!!
}
我正在使用Embarcadero RAD studio XE4 C ++ Builder,當我在主VCL線程中運行上面的代碼時,它運行正常。 當我使用多個連接運行它時,我在TThread
類的多個實例中運行上面的代碼,這是當我遇到訪問沖突的問題時 - 看來當connect
調用修改error_code
時,內部成員error_code
實例的m_cat
變為NULL,所以當我調用message()
我得到訪問沖突。 即使我只運行一個后台線程,也會發生這種情況。
上面的代碼是否有可能在我需要使用它的方式上不是線程安全的? 我試圖找出為什么這個代碼不會在后台線程中運行,但找不到任何關於它的東西。
我運行的升級版本是1.50,因為這是用於在RAD studio中構建64位應用程序的集成版本。
有沒有其他人在多線程設置中遇到此問題(在Embarcadero或其他方面),如果是這樣,你是如何解決它的? 或者這個類是不安全的以多線程方式使用?
這是一個很長的鏡頭,但它可能值得一試:
system::error_code
由兩個條目組成:錯誤值和類別。 錯誤值基本上只是一個int
,但類別是Singleton 。 這是必需的,因為基於指針標識比較錯誤類別的相等性(即,當且僅當它們指向相同的類別對象時,兩個類別相等)。
問題是Singleton類別的初始化可能不是線程安全的。 Asio使用system_category
,它在boost/libs/system/src/error_code.cpp
。 對於1.50,實現看起來像這樣:
BOOST_SYSTEM_DECL const error_category & system_category() BOOST_SYSTEM_NOEXCEPT
{
static const system_error_category system_category_const;
return system_category_const;
}
這保證在符合C ++ 11的編譯器上是線程安全的,但是如果你的編譯器沒有實現函數范圍靜態的線程安全初始化 ,那么這可能會破壞。 您可以通過跟蹤對此功能的調用輕松驗證這一點,看看您是否觀察到了潛在的競爭。
在多個示例中,他們在一個線程中調用io_service-> run(): http : //www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/example/cpp11/futures/daytime_client.cpp
我喜歡這個,使用了一個ThreadPool: 使用boost asio的線程池
你確定在某處調用了io_service-> run()嗎?
你必須始終確保iterator != boost::asio::ip::tcp::resolver::iterator()
。
來自boost docs:
默認構造的迭代器表示列表的結尾。
我敢打賭這是問題, connect()
只是因為無效的端點迭代器而破壞了堆棧。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.