boost::asio - 作为类成员启动链失败

问题描述 投票:0回答:1

尝试通过添加另一个 io_context 来启动链成员时,我的代码崩溃了

我有一堂带有 io_context 和一串的课程。现有的 io_context 是一个引用,它在构造函数中接收。我尝试使用新的 io_context 创建一条新链:

班级成员:

boost::asio::io_context& io_context_;
boost::asio::io_context io_context_2;
boost::asio::strand<boost::asio::io_context::executor_type> strand_;
boost::asio::strand<boost::asio::io_context::executor_type> strand_2;

构造者:

Server(
    boost::asio::io_context& ioc,
    : io_context_(ioc),
      io_context_2(),
      strand_(io_context_.get_executor()),
      strand_2(io_context_2.get_executor()),
       {
       }

我想让两条线具有不同的 io_context,但由于我试图测试崩溃,这也不起作用:

Server(
    boost::asio::io_context& ioc,
    : io_context_(ioc),
      io_context_2(),
      strand_(io_context_.get_executor()),
      strand_2(io_context_.get_executor()),
       {
       }

但确实如此:

Server(
    boost::asio::io_context& ioc,
    : io_context_(ioc),
      //io_context_2(),
      strand_(io_context_.get_executor()),
      strand_2(io_context_.get_executor()),
       {
       }

崩溃发生在启动strand_2的行中,在查看崩溃转储时似乎io_context_2无法启动 server.exe.9124.dmp 中 0x00007FFC8BD7FAAD (ntdll.dll) 处出现未处理的异常:0xC0000005:读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突。

在 win_mutex.hpp 中 - win_mutex::lock

c++ boost boost-asio
1个回答
0
投票

所描述的代码很好:

住在Coliru

#include <boost/asio.hpp>

namespace asio = boost::asio;

struct Server {
    using executor = asio::io_context::executor_type;
    asio::io_context&      io_context_;
    asio::io_context       io_context_2;
    asio::strand<executor> strand_;
    asio::strand<executor> strand_2;

    Server(asio::io_context& ioc)
        : io_context_(ioc)
        , io_context_2()
        , strand_(io_context_.get_executor())
        , strand_2(io_context_2.get_executor()) {}
};

int main() {
    asio::io_context ioc;

    Server s(ioc);

    ioc.run();
}

注意它如何与 ASan 和 UBsan 一起干净地运行。

猜测问题

因为代码被分成碎片,有许多语法错误,也可能存在拼写错误(第一个构造函数初始化列表可能应该说

strand_2(io_context_2.get_executor())
),我非常有信心地说你的真实代码看起来不同。

从中我基本上可以猜测问题是什么:

您还可以看到这个Live On Coliru

如果问题很难发现,您会发现编译器实际上会立即告诉您是否启用了最小警告:

g++ -std=c++20 -O2 -Wall -pedantic -pthread main.cpp -fsanitize=address,undefined && ./a.out
main.cpp: In constructor 'Server::Server(boost::asio::io_context&)':
main.cpp:10:28: warning: 'Server::strand_' will be initialized after [-Wreorder]
   10 |     asio::strand<executor> strand_;
      |                            ^~~~~~~
main.cpp:8:28: warning:   'boost::asio::strand<boost::asio::io_context::basic_executor_type<std::allocator<void>, 0> > Server::strand_2' [-Wreorder]
    8 |     asio::strand<executor> strand_2;
      |                            ^~~~~~~~
main.cpp:12:5: warning:   when initialized here [-Wreorder]
   12 |     Server(asio::io_context& ioc)

要理解的关键是字段是按照它们声明的顺序初始化的。这对于默认成员初始值设定项尤其有意义:https://en.cppreference.com/w/cpp/language/constructor#Initialization_order

因此,启用警告并阅读它们!

© www.soinside.com 2019 - 2024. All rights reserved.