C++ boost::system::error\u code::message()使用boost::asio套接字引发访问冲突异常

C++ boost::system::error\u code::message()使用boost::asio套接字引发访问冲突异常,c++,multithreading,boost-asio,c++builder-xe4,C++,Multithreading,Boost Asio,C++builder Xe4,我正在实现一个客户端应用程序,它必须与硬件设备进行少量套接字连接。我已经将问题分解为以下小代码子集 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_ser

我正在实现一个客户端应用程序,它必须与硬件设备进行少量套接字连接。我已经将问题分解为以下小代码子集

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!!!!

}

我使用了ActuCabro RAD工作室Xe4 C++ +Builder,当我在主VCL线程中运行上面的代码时,它运行良好。当我使用多个连接运行它时,我会在

TThread
类的多个实例中运行上面的代码,也就是当我遇到访问冲突的问题时-当
error\u code
connect
调用修改时,
error\u code
实例的内部成员
m\u cat
变为NULL,因此当我调用
message()
时,我得到了访问冲突。即使只有一个后台线程在运行,这种情况也会发生

我上面的代码有可能不是线程安全的吗?我试图找出为什么这段代码不会在后台线程中运行,但找不到任何关于它的信息

我运行的boost版本是1.50,因为这是用于在RAD studio中构建64位应用程序的集成版本


是否有其他人在多线程设置(Embarcadero或其他)中遇到此问题?如果是,您是如何解决的?或者该类以多线程方式使用是不安全的?

在多个示例中,它们在线程中调用io_service->run()

我喜欢这个,有一个线程池:


您确定io_service->run()在某个地方被调用了吗?

您必须始终确保
迭代器!=boost::asio::ip::tcp::resolver::iterator()

从boost文档:

默认构造的迭代器表示列表的结尾


我敢打赌这就是问题所在,
connect()
由于端点迭代器无效而中断堆栈。

这是一个很长的机会,但可能值得一试:

system::error\u code
由两个条目组成:错误值和类别。错误值基本上只是一个
int
,但类别是一个。这是必需的,因为根据指针标识比较错误类别是否相等(即,当且仅当两个类别指向同一类别对象时,两个类别才相等)

问题是,类别Singleton的初始化可能不是线程安全的。Asio使用
system\u类别
,该类别在
boost/libs/system/src/error\u 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_服务?我假设他们有不同的地址和端口组合来连接?第二,如果您知道地址和端口,您可以自己创建一个端点,而不是解析查询。您是否已检查迭代器是否实际包含任何端点?最后:我认为在使用迭代器时,应该使用非成员的
connect()
,但这可能是错误的。@DeVadder Yes每个线程都连接到一个不同的客户机,每个线程都有自己的io_服务。我会看看你提供的链接。ThanksI给人的印象是异步套接字需要这样做,而不是同步。谢谢。这是迄今为止我听到的最有用的建议。我会调查一下。