C++ Asio-不执行所有处理程序
我正在尝试为C++ Asio-不执行所有处理程序,c++,asynchronous,boost,boost-asio,C++,Asynchronous,Boost,Boost Asio,我正在尝试为boost::io_context创建一个适配器,它总是在准备好的处理程序中选择优先级最高的处理程序来执行。我从中得到了灵感,但很快在一个场景中遇到了意想不到的行为,在这个场景中,一个处理程序在相同的上下文中启动另一个异步操作 这是你的电话号码。我只修改了用户代码(在/-下面),以调用低优先级处理程序,之后我希望调用高优先级和中优先级处理程序。只调用低优先级处理程序 #include <boost/asio.hpp> #include <boost/function
boost::io_context
创建一个适配器,它总是在准备好的处理程序中选择优先级最高的处理程序来执行。我从中得到了灵感,但很快在一个场景中遇到了意想不到的行为,在这个场景中,一个处理程序在相同的上下文中启动另一个异步操作
这是你的电话号码。我只修改了用户代码(在/-
下面),以调用低优先级处理程序,之后我希望调用高优先级和中优先级处理程序。只调用低优先级处理程序
#include <boost/asio.hpp>
#include <boost/function.hpp>
#include <iostream>
#include <queue>
class handler_priority_queue
{
public:
void add(int priority, boost::function<void()> function)
{
handlers_.push(queued_handler(priority, function));
}
void execute_all()
{
while (!handlers_.empty())
{
queued_handler handler = handlers_.top();
handler.execute();
handlers_.pop();
}
}
// A generic wrapper class for handlers to allow the invocation to be hooked.
template <typename Handler>
class wrapped_handler
{
public:
wrapped_handler(handler_priority_queue& q, int p, Handler h)
: queue_(q), priority_(p), handler_(h)
{
}
void operator()()
{
handler_();
}
template <typename Arg1>
void operator()(Arg1 arg1)
{
handler_(arg1);
}
template <typename Arg1, typename Arg2>
void operator()(Arg1 arg1, Arg2 arg2)
{
handler_(arg1, arg2);
}
//private:
handler_priority_queue& queue_;
int priority_;
Handler handler_;
};
template <typename Handler>
wrapped_handler<Handler> wrap(int priority, Handler handler)
{
return wrapped_handler<Handler>(*this, priority, handler);
}
private:
class queued_handler
{
public:
queued_handler(int p, boost::function<void()> f)
: priority_(p), function_(f)
{
}
void execute()
{
function_();
}
friend bool operator<(const queued_handler& a,
const queued_handler& b)
{
return a.priority_ < b.priority_;
}
private:
int priority_;
boost::function<void()> function_;
};
std::priority_queue<queued_handler> handlers_;
};
// Custom invocation hook for wrapped handlers.
template <typename Function, typename Handler>
void asio_handler_invoke(Function f,
handler_priority_queue::wrapped_handler<Handler>* h)
{
h->queue_.add(h->priority_, f);
}
//----------------------------------------------------------------------
void high_priority_handler()
{
std::cout << "High priority handler\n";
}
void middle_priority_handler()
{
std::cout << "Middle priority handler\n";
}
void low_priority_handler(
boost::asio::io_service& io_service,
handler_priority_queue& pri_queue)
{
std::cout << "Low priority handler\n";
io_service.post(pri_queue.wrap(1, middle_priority_handler));
io_service.post(pri_queue.wrap(2, high_priority_handler));
}
int main()
{
boost::asio::io_service io_service;
handler_priority_queue pri_queue;
// Post a completion handler to be run immediately.
io_service.post(pri_queue.wrap(
0, std::bind(low_priority_handler,
std::ref(io_service), std::ref(pri_queue))));
while (io_service.run_one())
{
// The custom invocation hook adds the handlers to the priority queue
// rather than executing them from within the poll_one() call.
while (io_service.poll_one())
;
pri_queue.execute_all();
}
return 0;
}
#包括
#包括
#包括
#包括
类处理程序\u优先级\u队列
{
公众:
void add(int优先级,boost::function)
{
处理程序推送(队列处理程序(优先级、函数));
}
void execute_all()
{
而(!handlers.empty())
{
排队的_handler=handlers_u.top();
handler.execute();
处理程序.pop();
}
}
//用于处理程序的通用包装类,允许挂接调用。
模板
类包装的\u处理程序
{
公众:
包装处理程序(处理程序优先级队列&q、int p、处理程序h)
:队列(q)、优先级(p)、处理程序(h)
{
}
void运算符()()
{
handler_();
}
模板
void运算符()(Arg1 Arg1)
{
handler(arg1);
}
模板
void运算符()(Arg1 Arg1、Arg2 Arg2)
{
处理器(arg1,arg2);
}
//私人:
处理程序\u优先级\u队列和队列\u;
int优先权u2;;
处理程序;
};
模板
wrapped\u处理程序wrapp(int优先级,处理程序)
{
返回包装的处理程序(*此,优先级,处理程序);
}
私人:
类队列处理程序
{
公众:
排队_处理程序(int p,boost::function f)
:优先级(p),功能(f)
{
}
void execute()
{
函数_();
}
友元布尔运算符队列添加(h->priority,f);
}
//----------------------------------------------------------------------
无效高优先级处理程序()
{
std::coutio\u context
停止,因为在调用poll\u one
时没有任何准备好的处理程序可以运行
#include <boost/asio.hpp>
#include <boost/function.hpp>
#include <iostream>
#include <queue>
class handler_priority_queue
{
public:
void add(int priority, boost::function<void()> function)
{
handlers_.push(queued_handler(priority, function));
}
void execute_all()
{
while (!handlers_.empty())
{
queued_handler handler = handlers_.top();
handler.execute();
handlers_.pop();
}
}
// A generic wrapper class for handlers to allow the invocation to be hooked.
template <typename Handler>
class wrapped_handler
{
public:
wrapped_handler(handler_priority_queue& q, int p, Handler h)
: queue_(q), priority_(p), handler_(h)
{
}
void operator()()
{
handler_();
}
template <typename Arg1>
void operator()(Arg1 arg1)
{
handler_(arg1);
}
template <typename Arg1, typename Arg2>
void operator()(Arg1 arg1, Arg2 arg2)
{
handler_(arg1, arg2);
}
//private:
handler_priority_queue& queue_;
int priority_;
Handler handler_;
};
template <typename Handler>
wrapped_handler<Handler> wrap(int priority, Handler handler)
{
return wrapped_handler<Handler>(*this, priority, handler);
}
private:
class queued_handler
{
public:
queued_handler(int p, boost::function<void()> f)
: priority_(p), function_(f)
{
}
void execute()
{
function_();
}
friend bool operator<(const queued_handler& a,
const queued_handler& b)
{
return a.priority_ < b.priority_;
}
private:
int priority_;
boost::function<void()> function_;
};
std::priority_queue<queued_handler> handlers_;
};
// Custom invocation hook for wrapped handlers.
template <typename Function, typename Handler>
void asio_handler_invoke(Function f,
handler_priority_queue::wrapped_handler<Handler>* h)
{
h->queue_.add(h->priority_, f);
}
//----------------------------------------------------------------------
void high_priority_handler()
{
std::cout << "High priority handler\n";
}
void middle_priority_handler()
{
std::cout << "Middle priority handler\n";
}
void low_priority_handler(
boost::asio::io_service& io_service,
handler_priority_queue& pri_queue)
{
std::cout << "Low priority handler\n";
io_service.post(pri_queue.wrap(1, middle_priority_handler));
io_service.post(pri_queue.wrap(2, high_priority_handler));
}
int main()
{
boost::asio::io_service io_service;
handler_priority_queue pri_queue;
// Post a completion handler to be run immediately.
io_service.post(pri_queue.wrap(
0, std::bind(low_priority_handler,
std::ref(io_service), std::ref(pri_queue))));
while (io_service.run_one())
{
// The custom invocation hook adds the handlers to the priority queue
// rather than executing them from within the poll_one() call.
while (io_service.poll_one())
;
pri_queue.execute_all();
}
return 0;
}
[1] 第一个处理程序已发布:
io_service.post(pri_queue.wrap(0, std::bind(low_priority_handler,
std::ref(io_service), std::ref(pri_queue))));
[2] while(io_服务。运行_one())
等待直到有一个准备好的处理程序运行
[3] 在run\u one()
handler中执行。您已经定义了asio\u handler\u invoke()
,它提供了一些调用函数(主体)的策略默认策略只是调用函数,在您的情况下,函数对象被排队到handler\u priority\u queue
,但io\u服务的
队列不接收要执行的处理程序。因此,当低优先级\u处理程序的主体
(通过调用io\u service.post
)为io\u服务添加新的处理程序)是否执行?此函数从pri\u queue.execute\u all()
(在poll\u one
poll\u one()调用后调用),而不是在poll\u one()调用期间执行
将io\u服务
标记为在没有任何就绪处理程序可运行时停止。这是您的情况。您可以在pri\u队列之后重置io\u服务
。执行所有()
,则将调用所有处理程序。io_上下文
停止,因为在调用poll_one
时,没有任何准备好的处理程序可运行
#include <boost/asio.hpp>
#include <boost/function.hpp>
#include <iostream>
#include <queue>
class handler_priority_queue
{
public:
void add(int priority, boost::function<void()> function)
{
handlers_.push(queued_handler(priority, function));
}
void execute_all()
{
while (!handlers_.empty())
{
queued_handler handler = handlers_.top();
handler.execute();
handlers_.pop();
}
}
// A generic wrapper class for handlers to allow the invocation to be hooked.
template <typename Handler>
class wrapped_handler
{
public:
wrapped_handler(handler_priority_queue& q, int p, Handler h)
: queue_(q), priority_(p), handler_(h)
{
}
void operator()()
{
handler_();
}
template <typename Arg1>
void operator()(Arg1 arg1)
{
handler_(arg1);
}
template <typename Arg1, typename Arg2>
void operator()(Arg1 arg1, Arg2 arg2)
{
handler_(arg1, arg2);
}
//private:
handler_priority_queue& queue_;
int priority_;
Handler handler_;
};
template <typename Handler>
wrapped_handler<Handler> wrap(int priority, Handler handler)
{
return wrapped_handler<Handler>(*this, priority, handler);
}
private:
class queued_handler
{
public:
queued_handler(int p, boost::function<void()> f)
: priority_(p), function_(f)
{
}
void execute()
{
function_();
}
friend bool operator<(const queued_handler& a,
const queued_handler& b)
{
return a.priority_ < b.priority_;
}
private:
int priority_;
boost::function<void()> function_;
};
std::priority_queue<queued_handler> handlers_;
};
// Custom invocation hook for wrapped handlers.
template <typename Function, typename Handler>
void asio_handler_invoke(Function f,
handler_priority_queue::wrapped_handler<Handler>* h)
{
h->queue_.add(h->priority_, f);
}
//----------------------------------------------------------------------
void high_priority_handler()
{
std::cout << "High priority handler\n";
}
void middle_priority_handler()
{
std::cout << "Middle priority handler\n";
}
void low_priority_handler(
boost::asio::io_service& io_service,
handler_priority_queue& pri_queue)
{
std::cout << "Low priority handler\n";
io_service.post(pri_queue.wrap(1, middle_priority_handler));
io_service.post(pri_queue.wrap(2, high_priority_handler));
}
int main()
{
boost::asio::io_service io_service;
handler_priority_queue pri_queue;
// Post a completion handler to be run immediately.
io_service.post(pri_queue.wrap(
0, std::bind(low_priority_handler,
std::ref(io_service), std::ref(pri_queue))));
while (io_service.run_one())
{
// The custom invocation hook adds the handlers to the priority queue
// rather than executing them from within the poll_one() call.
while (io_service.poll_one())
;
pri_queue.execute_all();
}
return 0;
}
[1] 第一个处理程序已发布:
io_service.post(pri_queue.wrap(0, std::bind(low_priority_handler,
std::ref(io_service), std::ref(pri_queue))));
[2] while(io_服务。运行_one())
等待直到有一个准备好的处理程序运行
[3] 在run\u one()
handler中执行。您已经定义了asio\u handler\u invoke()
,它提供了一些调用函数(主体)的策略默认策略只是调用函数,在您的情况下,函数对象被排队到handler\u priority\u queue
,但io\u服务的
队列不接收要执行的处理程序。因此,当低优先级\u处理程序的主体
(通过调用io\u service.post
)为io\u服务添加新的处理程序)是否执行?此函数从pri\u queue.execute\u all()
(在poll\u one
poll\u one()调用后调用),而不是在poll\u one()调用期间执行
将io\u服务
标记为在没有任何准备好的处理程序运行时停止。这是您的情况。您可以在pri\u队列之后重置io\u服务
。执行\u all()
,然后调用所有处理程序