gpt4 book ai didi

c++ - 将 Boost.Coroutine 与 Boost.ASIO 一起使用会导致断言

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:38:10 25 4
gpt4 key购买 nike

我有在多个线程中运行的 boost::asio::io_context(通过 ctx.run()),我有几个在 boost.coroutines 中使用的异步对象,它们通过 boost::asio::运行产卵。我有以下断言:

Assertion failed: ! is_running(), file C:\boost\boost_1_68_0\msvc_x86\include\boost-1_68\boost\coroutine\detail\push_coroutine_impl.hpp, line 258

我提供了一个导致相同错误的最小示例。请帮助我:我做错了什么?

boost 版本为1.68

[更新]:代码中有一个修复(忘记锁定 io_context),但它不影响断言。

#include <iostream>
#include <thread>
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>

template<class CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(boost::system::error_code))
asyncDo(boost::asio::io_context& ctx, CompletionToken&& token)
{
using CompletionType = boost::asio::async_completion<CompletionToken, void(boost::system::error_code)>;
CompletionType completion{ token };
ctx.post(
[handler{ completion.completion_handler }](){
using boost::asio::asio_handler_invoke;
asio_handler_invoke(std::bind(handler, boost::system::error_code()), &handler);
return;
});
return completion.result.get();
}

void coroFunc(boost::asio::io_context& ctx, boost::asio::yield_context yield)
{
for (;;) {
std::cerr << std::this_thread::get_id() << '\n';
asyncDo(ctx, yield);
std::cerr << std::this_thread::get_id() << '\n';
}
}

int main(int, char* [])
{
boost::asio::io_context ctx;
boost::asio::executor_work_guard<boost::asio::io_context::executor_type> work(ctx.get_executor());

boost::asio::spawn(ctx, std::bind(coroFunc, std::ref(ctx), std::placeholders::_1));

std::thread([&ctx]() { ctx.run(); }).detach();
std::thread([&ctx]() { ctx.run(); }).detach();

std::cin.get();
work.reset();

return 0;
}

最佳答案

经过几个小时的谷歌搜索和尝试,我找到了适合我的解决方案(至少在我的测试中)。主要思想是将发布到 ctx 替换为发布到 associated executor:

    auto executor = boost::asio::get_associated_executor(completion.completion_handler, ctx);
auto allocator = boost::asio::get_associated_allocator(completion.completion_handler);

executor.post(
[handler = HandlerType{ std::move(completion.completion_handler) }](){
using boost::asio::asio_handler_invoke;
asio_handler_invoke(std::bind(handler, boost::system::error_code()), &handler);
return;
},
allocator);

完整代码:

#include <iostream>
#include <stdexcept>
#include <thread>
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>


template<class CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(boost::system::error_code))
asyncDo(boost::asio::io_context& ctx, CompletionToken&& token)
{
using CompletionType = boost::asio::async_completion<CompletionToken, void(boost::system::error_code)>;
using HandlerType = typename CompletionType::completion_handler_type;
CompletionType completion{ token };

auto executor = boost::asio::get_associated_executor(completion.completion_handler, ctx);
auto allocator = boost::asio::get_associated_allocator(completion.completion_handler);

executor.post(
[handler = HandlerType{ std::move(completion.completion_handler) }](){
using boost::asio::asio_handler_invoke;
asio_handler_invoke(std::bind(handler, boost::system::error_code()), &handler);
return;
},
allocator);

return completion.result.get();
}

void coroFunc(boost::asio::io_context& ctx, boost::asio::yield_context yield)
{
for (;;) {
try {
std::cerr << "(0): " << std::this_thread::get_id() << '\n';
asyncDo(ctx, yield);
std::cerr << "(1): " << std::this_thread::get_id() << '\n';
} catch (std::exception const& e) {
std::cerr << "e: " << e.what() << '\n';
}
}
}

int main(int, char* [])
{
boost::asio::io_context ctx;
boost::asio::executor_work_guard<boost::asio::io_context::executor_type> work(ctx.get_executor());

boost::asio::spawn(ctx, std::bind(coroFunc, std::ref(ctx), std::placeholders::_1));

std::thread([&ctx]() {
for (;;) {
try {
ctx.run();
break;
} catch (std::exception const& e) {
std::cerr << "e: " << e.what() << '\n';
}
}
}).detach();
std::thread([&ctx]() {
for (;;) {
try {
ctx.run();
break;
} catch (std::exception const& e) {
std::cerr << "e: " << e.what() << '\n';
}
}
}).detach();

std::cin.get();
work.reset();

return 0;
}

关于c++ - 将 Boost.Coroutine 与 Boost.ASIO 一起使用会导致断言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57667531/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com