C++ 使用Boost::Asio与我的RestAPI服务器进行http客户端连接,情况很好,但不知何故,堆损坏是我的1/20倍

C++ 使用Boost::Asio与我的RestAPI服务器进行http客户端连接,情况很好,但不知何故,堆损坏是我的1/20倍,c++,boost,boost-asio,heap-corruption,boost-beast,C++,Boost,Boost Asio,Heap Corruption,Boost Beast,下面是来自实际代码库的代码片段。请假定主机、端口、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 obj

下面是来自实际代码库的代码片段。请假定主机、端口、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();  
}

};
//连接建立器类
类CSSLConn:public std::从\u中启用\u共享\u
{
:  
: 
};
//用于维护线程池的类
类CHttpClient
{
//用于保存连接对象的向量
std::向量m_sslConnObj{};
//main方法调用它来创建连接
void-CHttpClient::初始化(int-nThreads)
{
对于(int x=0;x连接(sHost.c_str(),sPort.c_str());
m_sslConnObj.推回(客户);
ioc->run();
}
};
当它尝试创建线程池时,我有1/20次遇到堆损坏,主要是第二个线程。我怀疑std::vector,因为它在推送时分配内存(但我不确定它是真正的罪魁祸首)。我保持着连接的向量,以在最后断开所有连接

有时在“boost::system::error\u code background\u getaddrinfo”函数中会发生崩溃,但这里的所有值看起来都不错

我对boost不太熟悉,如果有人知道如何更好地调试它,我如何才能看到boost内部的情况将对我有很大帮助

  • 我看到从多个线程访问多个共享对象 在没有任何同步的情况下:

    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();
    }
    
    void WorkerThread(){
    自动客户端=标准::使共享(ioc、m_ctx、sHost、sPort);
    客户端->连接(sHost.c_str(),sPort.c_str());
    m_sslConnObj.推回(客户);
    ioc->run();
    }
    
    此处修改
    m_sslConnObj
    ,无需任何锁定。所以除非 这是一种线程安全的容器类型

  • 这同样适用于其他事情,如
    m_ctx

  • 这也是您发布异步工作的代码味道 分开线程,好像这意味着什么<代码>io_上下文是 从所有线程运行,因此您最好只运行线程 并从主线程创建所有客户端

  • 刚刚注意到,
    CSSLConn
    接受
    sHost
    sPort
    作为构造函数参数,但在调用
    connect()


  • 与valgrind、helgrind、ASAN、Uban、TSAN一起跑步。你可能有数据竞赛。这是100%的时间,不仅仅是你看到的情况。我提出了一些建议。下面是一个我认为“正常”的演示:请注意,ctx和m_sslConnObj现在仅从主线程修改。感谢您提供的示例代码。我会按照你的建议回去做修改。你怎么能写这么快的代码,我花了好长时间才理解所有这些细节(仍然只有一块)。我会让你知道我的结果。再次感谢。提示:你知道CodeReview.stackexchange.com吗?我仍然很感激这个链接,因为我通常不去那里是的,你是对的。批处理是最好的方法。因此,我一次完成了5k时间序列的批量生产。这减少了我推送客户机的次数。我喜欢使用单个线程来实现并发IO操作,但不知道如何使用Boost或C++来实现。我将尝试更多地阅读这方面的内容。让我起草一个简单明了的例子,说明我认为可行的方法。然后,您可以测量并决定哪些部件需要/值得调整。