使用 Boost::Asio 与我的 RestAPI 服务器进行 http 客户端连接,一切都很好,但不知何故,我遇到了 1/20 次堆损坏

问题描述

以下是来自实际代码库的代码片段。请假设主机、端口、ioc 都可用并已初始化。

// Connection establisher class
class CSSLConn: public std::enable_shared_from_this<CSSLConn>
{
   :  
   : 
};

// Class for maintaining the thread pool
class CHttpClient
{
  // vector to hold connction objects
  std::vector <std::shared_ptr<CSSLConn>>   m_sslConnObj{};


// main method call this to create connection
void CHttpClient::Initialize(int nThreads)
{
    for (int x = 0; x < nThreadCount; ++x)
    {
        worker_threads_.create_thread(boost::bind(&CHttpClient::WorkerThread,this));
    }

    // let connection get established
    std::this_thread::sleep_for(std::chrono::milliseconds(200));
}

// creating threads for thread pool
void CHttpClient::WorkerThread()
{
    auto client = std::make_shared<CSSLConn>(ioc,m_ctx,sHost,sPort);
    client->connect(sHost.c_str(),sPort.c_str());
    m_sslConnObj.push_back(client);
    ioc->run();  
}

};

1/20 次我在尝试创建线程池时遇到堆损坏,主要是使用第二个线程。我怀疑 std::vector,因为它在推送时分配内存(但我不确定它是否是真正的罪魁祸首)。我正在维护连接向量以在最后断开所有连接。

有时会在“boost::system::error_code background_getaddrinfo”函数中发生崩溃,但这里的所有值看起来都不错。

我对 boost 不太熟悉,如果有人知道如何更好地调试它,我怎么能看到 Boost 内部发生了什么,这对我有很大帮助。

解决方法

  1. 我看到多个共享对象被多个线程访问 没有任何同步:

    void WorkerThread() {
        auto client = std::make_shared<CSSLConn>(ioc,m_ctx,sHost,sPort);
        client->connect(sHost.c_str(),sPort.c_str());
        m_sslConnObj.push_back(client);
        ioc->run();
    }
    

    这里的 m_sslConnObj 是在没有加锁的情况下修改的。所以除非 这在某种程度上是一种线程安全的容器类型,这已经是 Undefined Behaviour

  2. m_ctx 等其他事物也是如此。

  3. 这也是你发布异步工作的代码味道 单独的线程,好像这意味着什么io_context 是 从所有线程运行,所以你不妨只运行线程 并从主线程创建所有客户端。 They will still be serviced from all the worker threads

  4. 刚刚注意到,CSSLConn 需要 sHostsPort 作为构造函数参数,但是当你调用 connect() 在他们身上你/再次/(但不同)传递他们。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...