evpp icon indicating copy to clipboard operation
evpp copied to clipboard

对TCPClient进行压力测试,segment fault退出

Open NewSetsu opened this issue 3 years ago • 0 comments

我的代码在某些场景中,可能会频繁打开、关闭TCPClient连接,于是做了个压力测试,发现程序会崩溃,想询问一下这是不是一个不正确的使用方式

测试代码如下

#include <memory>
#include <future>

#include <evpp/tcp_conn.h>
#include <evpp/tcp_client.h>
#include <evpp/tcp_server.h>
#include <evpp/tcp_conn.h>
#include <evpp/event_loop_thread.h>

#include <glog/logging.h>

using namespace evpp;

int main() {
    // 测试的server数量
    const int tnum = 4;
    
    auto base_thread = std::make_shared<evpp::EventLoopThread>();
    base_thread->Start(true);

    auto thread_pool = std::make_shared<evpp::EventLoopThreadPool>(base_thread->loop(), tnum * 2);
    thread_pool->Start(true);

    // 主线程同步future
    std::vector<std::future<void>> futures;

    for (int ti = 0; ti < tnum; ti++) {
        // 子线程的完成promise 子线程在执行结束后通过setvalue通知主线程结束等待
        std::shared_ptr<std::promise<void>> mp = std::make_shared<std::promise<void>>();
        futures.push_back(mp->get_future());
        std::thread tmp_t([=] {
            std::string s_port = std::to_string(28000 + ti);
            std::string s_ip = "0.0.0.0";
            auto s_addr = s_ip + ":" + s_port;
            auto m_svr = std::make_shared<TCPServer>(thread_pool->GetNextLoop(), s_addr, "tsvr", 1);
            m_svr->SetConnectionCallback([](const TCPConnPtr&) {});
            m_svr->SetMessageCallback([](const TCPConnPtr&, Buffer*) {});

            m_svr->Init();
            if (!m_svr->Start()) {
                LOG(ERROR) << "Svr start failed: " << s_addr;
            }

            for (int i = 0; i < 10000; i++) {
                auto m_cli = std::make_shared<TCPClient>(thread_pool->GetNextLoop(), s_addr, "tmp");
                m_cli->SetConnectionCallback([](const TCPConnPtr&) {});
                m_cli->SetMessageCallback([](const TCPConnPtr&, Buffer*) {});

                m_cli->Connect();
                while (true) { //等待连接
                    auto con = m_cli->conn();
                    if (con && con->IsConnected()) break;
                }
                m_cli->Disconnect();
                while (true) {//等待断开
                    auto con = m_cli->conn();
                    if (!con) break;
                }
                m_cli.reset();

            }

            m_svr->Stop();
            while (!m_svr->IsStopped()) {
                ;
            }
            mp->set_value();

            });
        tmp_t.detach();
    }

    for (auto& itor : futures) {
        itor.get();
    }

    thread_pool->Stop(true);
    base_thread->Stop(true);

    return 0;
}

执行结果

...
W0218 14:19:01.507688 11864 tcp_client.cc:65] TCPClient::DisconnectInLoop this=0x7f31a8001bb0 remote_addr=0.0.0.0:28002
W0218 14:19:01.508098 11857 tcp_client.cc:65] TCPClient::DisconnectInLoop this=0x7f3194001bb0 remote_addr=0.0.0.0:28003
[1]    11855 segmentation fault (core dumped)  ./EvppClient.out

NewSetsu avatar Feb 18 '22 06:02 NewSetsu