c++ - 如何使用 Handler 和 boost::asio::async_result
问题描述
如何使用 boost::asio::async_result,为什么我的代码崩溃(被信号 11:SIGSEGV 中断)
using ReadSignature = void(int);
template <class CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken , ReadSignature)
AsyncRead(boost::asio::io_service* ios,CompletionToken&& token) {
using Handler = typename boost::asio::handler_type<CompletionToken,
ReadSignature>::type;
Handler handler(std::forward<CompletionToken>(token));
boost::asio::async_result<Handler> result(handler);
std::cout << std::time(nullptr) << ":before thread" << std::endl;
std::thread thread([ios,&handler]() {
std::cout << std::time(nullptr) << ":run in thread before sleep"<< std::endl;
sleep(5);
std::cout << std::time(nullptr) << ":run in thread after sleep"<< std::endl;
std::cout << std::time(nullptr) << ":run in thread before cb" << std::endl;
ios->post([&handler](){
handler(2);
});
std::cout << std::time(nullptr) << ":run in thread after cb"<<std::endl;
});
thread.detach();
return result.get();
}
int main(int argc, char** argv) {
boost::asio::io_service s;
boost::asio::io_service::work worker(s);
boost::asio::spawn(s,[&s](boost::asio::yield_context yield){
boost::system::error_code er;
int val=AsyncRead(&s,yield[er]);
std::cout << std::time(nullptr) <<"get:"<<val<< "" << std::endl;
});
s.run();
return 0;
}
我期望:返回 result.get(); 将产生纤维,值 2 将得到。但代码崩溃:(被信号 11 中断:SIGSEGV),因为 handler.ec 为空。
解决方案
这样
ios->post([&handler](){
handler(2);
});
您创建排队的 lambda io_service
。这个闭包在内部执行io_service::run
。您通过引用捕获handler
本地内部AsyncRead
。何时handler(2)
调用
AsyncRead(&s,yield[er]);
协程在上面的行中恢复,result.get()
从调用AsyncRead
,AsyncRead
结束和处理程序作为局部变量被破坏,但执行的闭包io_service::run
仍然引用这个变量 - 未定义的行为。
您需要按值捕获处理程序,将其移动到线程和 lambda 中:
std::thread thread([ios,handler = std::move(handler)]() {
std::cout << std::time(nullptr) << ":run in thread before sleep"<< std::endl;
sleep(5);
std::cout << std::time(nullptr) << ":run in thread after sleep"<< std::endl;
std::cout << std::time(nullptr) << ":run in thread before cb" << std::endl;
ios->post([handler = std::move(handler)]() mutable {
handler(2);
});
std::cout << std::time(nullptr) << ":run in thread after cb"<<std::endl;
});
推荐阅读
- c++ - Cout 在里面吗?
- javascript - 数组元素显示两次
- ios - UIPopOverPresentationController 在presentationTransitionWillBegin 上崩溃
- reactjs - 在 TypeScript 中的 Formik 验证中分配错误消息不起作用
- docker - 如何授予 Openshift 容器的非特权用户对 /root/.ssh 的读取权限以进行 Spring Cloud Config Server SSH 身份验证?
- ios - PostGraphile 和 Swift (SwiftUI) 集成
- python - 为什么虽然触发了视图,但评论对象没有从数据库中删除?
- python - Python pandas:为什么 `del df.loc[:,column_name]` 不起作用?(即使 `del df[column_name]` 可以?
- angular - 如何更改引导轮播项目Angular
- java - 使用 Spring Autowired 注解的要求