You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Boost Asio客户端服务端程序崩溃求助:std::system_error死锁避免

解决服务端线程join时的资源死锁异常

嘿,这个问题的根源一眼就能看穿——你在让线程尝试等待自己结束,这直接触发了系统的资源死锁检测,所以抛出了Resource deadlock avoided异常。

问题具体分析

看你的Service类代码逻辑:

  • 在StartHandligClient方法中,你创建了一个新线程,这个线程的执行体就是HandleClient函数,同时把这个线程的指针存在了m_thread成员变量里。
  • 然后在HandleClient函数的末尾,你调用了m_thread->join()——但此时m_thread指向的就是当前正在运行HandleClient的线程!线程等待自己结束,这是不可能完成的操作,系统自然会抛出死锁异常。

另外还有个潜在问题:你在HandleClient里直接delete this,这种手动管理内存的方式很容易导致悬空指针或者内存泄漏,建议用智能指针来管理Service实例。

修复方案

  1. 移除自join的代码:删掉HandleClient里的m_thread->join()调用,线程完全不需要等待自己结束。
  2. 用智能指针管理Service生命周期:把new Service改成std::make_shared<Service>,让线程结束后自动释放资源,彻底避免手动delete带来的风险。

修改后的服务端核心代码

#include <boost/asio.hpp>
#include <thread>
#include <atomic>
#include <memory>
#include <iostream>
using namespace boost;

class Service {
public:
    Service(){} 
    void StartHandligClient( std::shared_ptr<asio::ip::tcp::socket> sock) {
        // 不需要把线程存在成员变量,直接detach让线程后台运行
        std::thread([this, sock]() { HandleClient(sock); }).detach(); 
    }
private:
    void HandleClient(std::shared_ptr<asio::ip::tcp::socket> sock) {
        while(1) {
            try {
                asio::streambuf request;
                std::cout << "Waiting to read \n";
                asio::read_until(*sock.get(), request, '\n');
                std::string s( (std::istreambuf_iterator<char>(&request)), std::istreambuf_iterator<char>() );
                std::cout << "Server got : " << s << "\n";
                // Emulate request processing.
                int i = 0;
                while (i != 1000000) i++;
                std::this_thread::sleep_for( std::chrono::milliseconds(500));
                // Sending response.
                std::string response = "Response\n";
                asio::write(*sock.get(), asio::buffer(response));
            } catch (system::system_error &e) {
                boost::system::error_code ec = e.code();
                if(ec == asio::error::eof) {
                    std::cout << "Breaking loop \n";
                    break;
                }
                std::cout << "Error occured! Error code = " << e.code() << ". Message: " << e.what();
            }
        }
        // 移除原有的join和delete this,线程结束后自动销毁资源
    }
    // 删掉不必要的m_thread成员变量
};

class Acceptor {
public:
    Acceptor(asio::io_service& ios, unsigned short port_num) : m_ios(ios), m_acceptor(m_ios, asio::ip::tcp::endpoint( asio::ip::address_v4::any(), port_num)) {
        m_acceptor.listen();
    }
    void Accept() {
        std::cout << "Server Accept() \n" << std::flush;
        std::shared_ptr<asio::ip::tcp::socket> sock(new asio::ip::tcp::socket(m_ios));
        std::cout << "BEFORE calling acceptor's accept function \n" << std::flush;
        m_acceptor.accept(*sock.get());
        std::cout << "AFTER calling acceptor's accept function \n" << std::flush;
        // 用shared_ptr管理Service实例,避免手动delete
        auto service = std::make_shared<Service>();
        service->StartHandligClient(sock);
    }
    void close() {
        std::cout << "Inside Acceptor.close() \n" << std::flush;
        m_acceptor.close();
    }
private:
    asio::io_service& m_ios;
    asio::ip::tcp::acceptor m_acceptor;
};

// Server类保持原有逻辑不变
class Server {
public:
    Server() : m_stop(false) {}
    void Start(unsigned short port_num) {
        m_thread.reset(new std::thread([this, port_num]() { Run(port_num); }));
    }
    void Stop() {
        m_stop.store(true);
        m_thread->join();
    }
private:
    void Run(unsigned short port_num) {
        Acceptor acc(m_ios, port_num);
        while (!m_stop.load()) {
            std::cout << "Server accept\n" << std::flush;
            acc.Accept();
        }
        acc.close();
    }
    std::unique_ptr<std::thread> m_thread;
    std::atomic<bool> m_stop;
    asio::io_service m_ios;
};

int main() {
    unsigned short port_num = 3333;
    try {
        Server srv;
        srv.Start(port_num);
        std::this_thread::sleep_for(std::chrono::seconds(4));
        srv.Stop();
    } catch (system::system_error &e) {
        std::cout << "Error occured! Error code = " << e.code() << ". Message: " << e.what();
    }
    return 0;
}

额外说明

  • 我们把线程改成detach(),让它在后台独立运行,不需要主线程等待它结束,这更符合服务端并发处理客户端请求的场景。
  • 用std::shared_ptr<Service>管理服务实例,当线程结束后,智能指针会自动释放资源,彻底避免了手动delete带来的内存泄漏或悬空指针问题。
  • 现在服务端可以正常处理客户端请求,当Server::Stop()被调用时,会正常关闭acceptor,不会再出现死锁异常,能和客户端一样正常退出。

内容的提问来源于stack exchange,提问作者Nishant Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:08:32