尝试通过添加另一个 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
所描述的代码很好:
#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
因此,启用警告并阅读它们!