Boost 1.70 io_service 弃用
Boost 1.70 io_service deprecation
我正在尝试将一些旧代码从使用 io_service 迁移到 io_context 用于基本 tcp 接受器,但是 运行 在切换 get_io_service 时遇到问题() 到 get_executor().context() 导致以下错误:
cannot convert ‘boost::asio::execution_context’ to ‘boost::asio::io_context&’
这是监听器:
ImageServerListener::ImageServerListener(boost::asio::io_context& io)
{
_acceptor = new boost::asio::ip::tcp::acceptor(io, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), sConfig.net.imageServerPort));
StartAccept();
}
ImageServerListener::~ImageServerListener()
{
delete _acceptor;
}
void ImageServerListener::StartAccept()
{
std::shared_ptr<ImageServerConnection> connection = ImageServerConnection::create(_acceptor->get_executor().context());
_acceptor->async_accept(connection->socket(), std::bind(&ImageServerListener::HandleAccept, this, connection));
}
void ImageServerListener::HandleAccept(std::shared_ptr<ImageServerConnection> connection)
{
connection->Process();
StartAccept();
}
为了 return 一个 io_context 而不是 execution_context 需要改变什么?
您将希望关注执行者而不是上下文。
传递执行器很便宜,它们是可复制的,而不是上下文。
此外,它抽象(多态)执行程序所附加的执行上下文类型,因此您无需费心。
但是,执行器的static类型不固定。这意味着接受一个的典型方法是通过模板参数:
struct MyThing {
template <typename Executor>
explicit MyThing(Executor ex)
: m_socket(ex)
{ }
void do_stuff(std::string caption) {
post(m_socket.get_executor(),
[=] { std::cout << ("Doing stuff " + caption + "\n") << std::flush; });
}
// ...
private:
tcp::socket m_socket;
};
现在您可以在很多方面使用它而无需更改:
int main() {
boost::asio::thread_pool pool;
MyThing a(pool.get_executor());
MyThing b(make_strand(pool));
a.do_stuff("Pool a");
b.do_stuff("Pool b");
boost::asio::io_context ioc;
MyThing c(ioc.get_executor());
MyThing d(make_strand(ioc));
c.do_stuff("IO c");
d.do_stuff("IO d");
pool.join();
ioc.run();
}
这将打印类似
的内容
Doing stuff Pool a
Doing stuff Pool b
Doing stuff IO c
Doing stuff IO d
类型擦除
您可能已经猜到,m_socket
中存在类型擦除,用于存储执行程序。如果你想做同样的事情,你可以使用
boost::asio::any_io_executor ex;
ex = m_socket.get_executor();
我正在尝试将一些旧代码从使用 io_service 迁移到 io_context 用于基本 tcp 接受器,但是 运行 在切换 get_io_service 时遇到问题() 到 get_executor().context() 导致以下错误:
cannot convert ‘boost::asio::execution_context’ to ‘boost::asio::io_context&’
这是监听器:
ImageServerListener::ImageServerListener(boost::asio::io_context& io)
{
_acceptor = new boost::asio::ip::tcp::acceptor(io, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), sConfig.net.imageServerPort));
StartAccept();
}
ImageServerListener::~ImageServerListener()
{
delete _acceptor;
}
void ImageServerListener::StartAccept()
{
std::shared_ptr<ImageServerConnection> connection = ImageServerConnection::create(_acceptor->get_executor().context());
_acceptor->async_accept(connection->socket(), std::bind(&ImageServerListener::HandleAccept, this, connection));
}
void ImageServerListener::HandleAccept(std::shared_ptr<ImageServerConnection> connection)
{
connection->Process();
StartAccept();
}
为了 return 一个 io_context 而不是 execution_context 需要改变什么?
您将希望关注执行者而不是上下文。
传递执行器很便宜,它们是可复制的,而不是上下文。
此外,它抽象(多态)执行程序所附加的执行上下文类型,因此您无需费心。
但是,执行器的static类型不固定。这意味着接受一个的典型方法是通过模板参数:
struct MyThing {
template <typename Executor>
explicit MyThing(Executor ex)
: m_socket(ex)
{ }
void do_stuff(std::string caption) {
post(m_socket.get_executor(),
[=] { std::cout << ("Doing stuff " + caption + "\n") << std::flush; });
}
// ...
private:
tcp::socket m_socket;
};
现在您可以在很多方面使用它而无需更改:
int main() {
boost::asio::thread_pool pool;
MyThing a(pool.get_executor());
MyThing b(make_strand(pool));
a.do_stuff("Pool a");
b.do_stuff("Pool b");
boost::asio::io_context ioc;
MyThing c(ioc.get_executor());
MyThing d(make_strand(ioc));
c.do_stuff("IO c");
d.do_stuff("IO d");
pool.join();
ioc.run();
}
这将打印类似
的内容Doing stuff Pool a
Doing stuff Pool b
Doing stuff IO c
Doing stuff IO d
类型擦除
您可能已经猜到,m_socket
中存在类型擦除,用于存储执行程序。如果你想做同样的事情,你可以使用
boost::asio::any_io_executor ex;
ex = m_socket.get_executor();