首页 > 解决方案 > asio::io_service::run 在 boost::asio::io_service::work 被销毁后不返回

问题描述

正如标题所说,当我不明白为什么这个线程时,我遇到了这个问题

在此处输入图像描述

即使在Client's 析构函数破坏asio::io_service::work变量后也不会停止运行

在此处输入图像描述

当我运行这个程序输出总是这样

在此处输入图像描述

有人看到我在这里缺少什么吗?

#include <boost/asio.hpp>
#include <thread>
#include <atomic>
#include <memory>

using namespace boost;


class Client{
public:

    Client(const Client& other) = delete;

    Client()
    {
        m_work.reset(new boost::asio::io_service::work(m_ios));

        m_thread.reset(new std::thread([this]()
        {
            m_ios.run();
        }));
    }

    ~Client(){ close(); }

private:

    void close();

    asio::io_service m_ios;
    std::unique_ptr<boost::asio::io_service::work> m_work;
    std::unique_ptr<std::thread> m_thread;

};

void Client::close()
{
    m_work.reset(nullptr);

    if(m_thread->joinable())
    {
        std::cout << "before joining thread" << std::endl;
        m_thread->join();
        std::cout << "after joining thread" << std::endl;
    }
}



int main()
{
    {
         Client client;
    }

    return 0;
}

编辑


StPiere发表评论后,我将代码更改为此并且它有效:)

class Client{
public:

    Client(const Client& other) = delete;

    Client()
    {
        m_work.reset(new boost::asio::executor_work_guard<boost::asio::io_context::executor_type>(boost::asio::make_work_guard(m_ios)));
        m_thread.reset(new std::thread([this]()
        {
            m_ios.run();
        }));
    }

    ~Client(){ close(); }

private:

    void close();

    asio::io_context m_ios;

    std::unique_ptr<boost::asio::executor_work_guard<boost::asio::io_context::executor_type>> m_work;
    std::unique_ptr<std::thread> m_thread;

};

标签: c++boostasio

解决方案


我无法在任一编译器上重现该错误。这里是 gcc 9.3 和 boost 1.73 的示例

通常,工作析构函数会使用类似InterLockedDecrement在 Windows 上的东西来减少未完成作品的数量。

它看起来像一些编译器或 io_service/work 实现问题。

如评论中所述,io_service并且在和io_service::work方面已弃用io_contextexecutor_work_guard


推荐阅读