Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
即使正确使用make_shared,shared_from_this()也会导致std::bad_-weak_-ptr 我正在使用独立的Asio和C++ 11创建一个C++服务器应用程序,而AM会出错,这就是我请求帮助的原因。 错误_C++_C++11_Boost Asio_Shared Ptr - Fatal编程技术网

即使正确使用make_shared,shared_from_this()也会导致std::bad_-weak_-ptr 我正在使用独立的Asio和C++ 11创建一个C++服务器应用程序,而AM会出错,这就是我请求帮助的原因。 错误

即使正确使用make_shared,shared_from_this()也会导致std::bad_-weak_-ptr 我正在使用独立的Asio和C++ 11创建一个C++服务器应用程序,而AM会出错,这就是我请求帮助的原因。 错误,c++,c++11,boost-asio,shared-ptr,C++,C++11,Boost Asio,Shared Ptr,在类worker\u线程中,在从\u this()调用shared\u期间,会引发坏的\u弱的\u ptr异常,从而导致程序崩溃 布局 类connection\u manager在std::vector容器中创建并存储类型为std::shared\u ptr的对象 类worker\u线程继承自std::enable\u shared\u from\u this 类worker\u thread创建类型为std::shared\u ptr的对象 类连接需要指向类工作线程的指针(这是一个共享指针),

在类
worker\u线程
中,在从\u this()调用
shared\u期间,会引发
坏的\u弱的\u ptr
异常,从而导致程序崩溃

布局
  • connection\u manager
    std::vector
    容器中创建并存储类型为
    std::shared\u ptr
    的对象
  • worker\u线程
    继承自
    std::enable\u shared\u from\u this
  • worker\u thread
    创建类型为
    std::shared\u ptr
    的对象
  • 连接
    需要指向类
    工作线程
    的指针(这是一个共享指针),以便in可以调用
    无效句柄_finish(std::shared_ptr)
  • 程序流程
  • worker\u线程
    是通过其构造函数从类
    connection\u manager
    使用
    std::make\u shared
    创建的,其中有两个共享指针作为参数
  • connection\u管理器从
    worker\u线程调用
    void init()
  • 在程序的后面部分,
    connection\u manager
    调用
    std::shared\u ptr get\u available\u connection()
    from
    worker\u thread
  • 在此方法执行期间,通过
    std::make_shared
    创建一个新的
    连接
    ,其中一个参数是指向当前
    工作线程的共享指针,该线程是通过
    shared_from_this()获得的
  • 在调用
    shared\u from_this()
    过程中,程序崩溃,出现
    bad\u弱\u ptr
    异常
  • 研究 根据我的研究,这种错误最常见的原因是:

  • shared\u from\u在构造函数(或构造函数调用的函数)中调用this()
  • 当没有指向对象的现有
    std::shared_ptr
  • 在我的节目中:

  • 对构造函数的调用和对
    get\u available\u connection()
    的调用是分开的,通过终端中的输出行,似乎在调用
    get\u available\u connection()
    时,构建并初始化了
    worker\u线程
  • connection\u管理器
    类持有指向每个
    worker\u线程
    对象的共享指针
  • 代码 所有
    something\u ptr
    都是
    std::shared\u ptr

    typedef asio::executor_work_guard<asio::io_context::executor_type>
        io_context_work;
    std::vector<worker_thread_ptr> workers;
    std::vector<io_context_ptr> io_contexts;
    std::vector<io_context_work> work;
    
    class worker_thread : std::enable_shared_from_this<worker_thread> {
    public:
    
    /// Create a worker thread.
    explicit worker_thread(io_context_ptr io, config_ptr vars_global);
    
    void init();
    void join();
    
    connection_ptr get_available_connection();
    //...
    
    explicit connection(std::shared_ptr<worker_thread> worker,
                std::shared_ptr<asio::io_context> io, 
                config_ptr vars_parent);
    
    connection_manager::connection_manager(config_ptr vars) {
        std::size_t number_of_threads = vars->worker_threads;
        while(number_of_threads > 0) {
            io_context_ptr io_context(new asio::io_context);
            io_contexts.push_back(io_context);
            work.push_back(asio::make_work_guard(*io_context));
    
            worker_thread_ptr worker =
                std::make_shared<worker_thread>(io_context, vars);
            workers.push_back(worker);
    
            worker->init();
    
            --number_of_threads;
        }   
    } 
    
    connection_ptr connection_manager::get_available_connection() {
        std::size_t index_of_min_thread = 0;
        std::size_t worker_count = workers.size();
        for(std::size_t i = 1; i < worker_count; ++i) {
            if(workers[i]->active_connection_count() <
                    workers[index_of_min_thread]->active_connection_count())
                index_of_min_thread = i;
        }
        return workers[index_of_min_thread]->get_available_connection();
    }
    
    worker_thread::worker_thread(io_context_ptr io, 
            config_ptr vars_global)
        :io_context(io), active_conn_count(0), vars(vars_global),
        worker(
            [this]() {
                if(io_context)
                    io_context->run();
            }   
        ) {}
    
    void worker_thread::init() {
        //Additional initialisation, this is called by connection_manager
        //after this thread's construction
    }   
    
    connection_ptr worker_thread::get_available_connection() {
        connection_ptr conn;
        if(!available_connections.empty()) {
            conn = available_connections.front();
            available_connections.pop();
            active_connections.insert(conn);
            return conn;
        } else {
            conn = std::make_shared<connection>(shared_from_this(), io_context, vars);
            active_connections.insert(conn);
            return conn;
        }
    }
    
    头文件
    连接管理器.hpp

    typedef asio::executor_work_guard<asio::io_context::executor_type>
        io_context_work;
    std::vector<worker_thread_ptr> workers;
    std::vector<io_context_ptr> io_contexts;
    std::vector<io_context_work> work;
    
    class worker_thread : std::enable_shared_from_this<worker_thread> {
    public:
    
    /// Create a worker thread.
    explicit worker_thread(io_context_ptr io, config_ptr vars_global);
    
    void init();
    void join();
    
    connection_ptr get_available_connection();
    //...
    
    explicit connection(std::shared_ptr<worker_thread> worker,
                std::shared_ptr<asio::io_context> io, 
                config_ptr vars_parent);
    
    connection_manager::connection_manager(config_ptr vars) {
        std::size_t number_of_threads = vars->worker_threads;
        while(number_of_threads > 0) {
            io_context_ptr io_context(new asio::io_context);
            io_contexts.push_back(io_context);
            work.push_back(asio::make_work_guard(*io_context));
    
            worker_thread_ptr worker =
                std::make_shared<worker_thread>(io_context, vars);
            workers.push_back(worker);
    
            worker->init();
    
            --number_of_threads;
        }   
    } 
    
    connection_ptr connection_manager::get_available_connection() {
        std::size_t index_of_min_thread = 0;
        std::size_t worker_count = workers.size();
        for(std::size_t i = 1; i < worker_count; ++i) {
            if(workers[i]->active_connection_count() <
                    workers[index_of_min_thread]->active_connection_count())
                index_of_min_thread = i;
        }
        return workers[index_of_min_thread]->get_available_connection();
    }
    
    worker_thread::worker_thread(io_context_ptr io, 
            config_ptr vars_global)
        :io_context(io), active_conn_count(0), vars(vars_global),
        worker(
            [this]() {
                if(io_context)
                    io_context->run();
            }   
        ) {}
    
    void worker_thread::init() {
        //Additional initialisation, this is called by connection_manager
        //after this thread's construction
    }   
    
    connection_ptr worker_thread::get_available_connection() {
        connection_ptr conn;
        if(!available_connections.empty()) {
            conn = available_connections.front();
            available_connections.pop();
            active_connections.insert(conn);
            return conn;
        } else {
            conn = std::make_shared<connection>(shared_from_this(), io_context, vars);
            active_connections.insert(conn);
            return conn;
        }
    }
    
    连接.hpp

    typedef asio::executor_work_guard<asio::io_context::executor_type>
        io_context_work;
    std::vector<worker_thread_ptr> workers;
    std::vector<io_context_ptr> io_contexts;
    std::vector<io_context_work> work;
    
    class worker_thread : std::enable_shared_from_this<worker_thread> {
    public:
    
    /// Create a worker thread.
    explicit worker_thread(io_context_ptr io, config_ptr vars_global);
    
    void init();
    void join();
    
    connection_ptr get_available_connection();
    //...
    
    explicit connection(std::shared_ptr<worker_thread> worker,
                std::shared_ptr<asio::io_context> io, 
                config_ptr vars_parent);
    
    connection_manager::connection_manager(config_ptr vars) {
        std::size_t number_of_threads = vars->worker_threads;
        while(number_of_threads > 0) {
            io_context_ptr io_context(new asio::io_context);
            io_contexts.push_back(io_context);
            work.push_back(asio::make_work_guard(*io_context));
    
            worker_thread_ptr worker =
                std::make_shared<worker_thread>(io_context, vars);
            workers.push_back(worker);
    
            worker->init();
    
            --number_of_threads;
        }   
    } 
    
    connection_ptr connection_manager::get_available_connection() {
        std::size_t index_of_min_thread = 0;
        std::size_t worker_count = workers.size();
        for(std::size_t i = 1; i < worker_count; ++i) {
            if(workers[i]->active_connection_count() <
                    workers[index_of_min_thread]->active_connection_count())
                index_of_min_thread = i;
        }
        return workers[index_of_min_thread]->get_available_connection();
    }
    
    worker_thread::worker_thread(io_context_ptr io, 
            config_ptr vars_global)
        :io_context(io), active_conn_count(0), vars(vars_global),
        worker(
            [this]() {
                if(io_context)
                    io_context->run();
            }   
        ) {}
    
    void worker_thread::init() {
        //Additional initialisation, this is called by connection_manager
        //after this thread's construction
    }   
    
    connection_ptr worker_thread::get_available_connection() {
        connection_ptr conn;
        if(!available_connections.empty()) {
            conn = available_connections.front();
            available_connections.pop();
            active_connections.insert(conn);
            return conn;
        } else {
            conn = std::make_shared<connection>(shared_from_this(), io_context, vars);
            active_connections.insert(conn);
            return conn;
        }
    }
    
    worker\u thread.cpp

    typedef asio::executor_work_guard<asio::io_context::executor_type>
        io_context_work;
    std::vector<worker_thread_ptr> workers;
    std::vector<io_context_ptr> io_contexts;
    std::vector<io_context_work> work;
    
    class worker_thread : std::enable_shared_from_this<worker_thread> {
    public:
    
    /// Create a worker thread.
    explicit worker_thread(io_context_ptr io, config_ptr vars_global);
    
    void init();
    void join();
    
    connection_ptr get_available_connection();
    //...
    
    explicit connection(std::shared_ptr<worker_thread> worker,
                std::shared_ptr<asio::io_context> io, 
                config_ptr vars_parent);
    
    connection_manager::connection_manager(config_ptr vars) {
        std::size_t number_of_threads = vars->worker_threads;
        while(number_of_threads > 0) {
            io_context_ptr io_context(new asio::io_context);
            io_contexts.push_back(io_context);
            work.push_back(asio::make_work_guard(*io_context));
    
            worker_thread_ptr worker =
                std::make_shared<worker_thread>(io_context, vars);
            workers.push_back(worker);
    
            worker->init();
    
            --number_of_threads;
        }   
    } 
    
    connection_ptr connection_manager::get_available_connection() {
        std::size_t index_of_min_thread = 0;
        std::size_t worker_count = workers.size();
        for(std::size_t i = 1; i < worker_count; ++i) {
            if(workers[i]->active_connection_count() <
                    workers[index_of_min_thread]->active_connection_count())
                index_of_min_thread = i;
        }
        return workers[index_of_min_thread]->get_available_connection();
    }
    
    worker_thread::worker_thread(io_context_ptr io, 
            config_ptr vars_global)
        :io_context(io), active_conn_count(0), vars(vars_global),
        worker(
            [this]() {
                if(io_context)
                    io_context->run();
            }   
        ) {}
    
    void worker_thread::init() {
        //Additional initialisation, this is called by connection_manager
        //after this thread's construction
    }   
    
    connection_ptr worker_thread::get_available_connection() {
        connection_ptr conn;
        if(!available_connections.empty()) {
            conn = available_connections.front();
            available_connections.pop();
            active_connections.insert(conn);
            return conn;
        } else {
            conn = std::make_shared<connection>(shared_from_this(), io_context, vars);
            active_connections.insert(conn);
            return conn;
        }
    }
    
    worker\u线程::worker\u线程(io\U上下文\U ptr io,
    配置变量(全局)
    :io上下文(io)、活动连接计数(0)、变量(变量全局),
    工人(
    [这](){
    如果(io_上下文)
    io_上下文->运行();
    }   
    ) {}
    无效工作线程::init(){
    //附加初始化,由连接管理器调用
    //在这个线程的构造之后
    }   
    连接\u ptr工作线程::获取可用的\u连接(){
    连接接头;
    如果(!available_connections.empty()){
    conn=可用的_连接。前();
    可用的_连接。pop();
    活动_连接。插入(连接);
    返回连接;
    }否则{
    conn=std::make_shared(来自_this()、io_上下文、vars的共享_);
    活动_连接。插入(连接);
    返回连接;
    }
    }
    
    如果这个问题以前被回答过,我很抱歉,但我试图解决这个问题,在尝试了一段时间后,我决定最好寻求帮助

    编辑 这是一个最低限度的测试,它失败了。它需要CMake,并且您可能必须更改所需的最低版本


    我认为您的问题可能是使用默认的
    私有继承

    下面是一个程序崩溃的简单示例:

    class GoodUsage : public std::enable_shared_from_this<GoodUsage>
    {
    public:
        void DoSomething()
        {
            auto good = shared_from_this();
        }
    };
    
    class BadUsage : std::enable_shared_from_this<BadUsage> // private inheritance
    {
    public:
        void DoSomething()
        {
            auto bad = shared_from_this();
        }
    };
    
    
    int main()
    {
        auto good = std::make_shared<GoodUsage>();
        auto bad = std::make_shared<BadUsage>();
        good->DoSomething(); // ok
        bad->DoSomething(); // throws std::bad_weak_ptr    
    }
    
    class-GoodUsage:public-std::从\u中启用\u共享\u
    {
    公众:
    无效剂量测定法()
    {
    auto good=从_this()共享_;
    }
    };
    类BadUsage:std::从\u这个//私有继承中启用\u共享\u
    {
    公众:
    无效剂量测定法()
    {
    auto bad=从_this()共享_;
    }
    };
    int main()
    {
    自动良好=标准::使_共享();
    auto bad=std::make_shared();
    好->DoSomething();//好的
    bad->DoSomething();//抛出std::bad_弱_ptr
    }
    
    请花点时间阅读。我没有看到任何常见错误。您是否检查过没有因为多线程访问而中断任何内容?(必要时使用锁),有时这种错误会导致某些内存损坏,或者是某些“未定义行为”的后续operation@PetarNikić
    class
    es默认为私有继承。看到了,很高兴是这样。看来我在答案上被打败了@NinaKaprez的回答涵盖了这一点。重新编写了标题,使其成为针对这一反复出现的陷阱的优秀搜索。(我以前见过,但我花了太长时间才再次意识到这一点)。这东西是用来做的