支持异步I/O功能
Boost::asio::io_context是异步I/O的核心功能,io_context提供用户的异步I/O对象的的核心I/O功能,包含:
(1) boost::asio::ip::tcp::socket
(2) boost::asio::ip::tcp::acceptor
(3) boost::asio::ip::upd::socket
(4) boost::asio::deadline_timer
io_context也实现为用户提供自定义异步服务的功能
安全性
(1) 对于不同对象,线程安全
(2) 对于共享对象,除了restart() 和 notify_fork()功能包含特定的异常外,线程安全的。当run(), run_one(), run_for(), run_until(), poll() 和 poll_one()未执行完前,调用restart()将导致未定义的行为。当任何io_context功能以及任何关联io_context的I/O对象的函数在另外一个线程被调用时,不能够调用notify_fork()函数
同步和异步操作
(1) 对于同步I/O情况,对于每一个I/O操作都将隐含执行一个io_context对象
(2) 对于异步I/O情况,io_context的函数run(), run_one(), run_for(), run_until(), poll() 或 poll_one()必须在io_context执行异步操作行为前被调用,注意,一个异步操作完成的标志是关联的handler被调用。handler会在任何当前执行run(), run_one(), run_for(), run_until(), poll()或 poll_one()的线程中执行
handler 的异常
如果异常由handler产生,异常允许从调用io_context的run(), run_one(), run_for(), run_until(), poll() 或 poll_one()的线程传播,并不会影响其他线程。用户需要处理异常。
当异常被捕获,run(), run_one(), run_for(), run_until(), poll() 或 poll_one()会自动调用restart(),并不需要其他介入调用restart(),这样,能够允许线程重新加入io_context对象的线程池而不影响其他已经在线程池中的线程
例如
boost::asio::io_context io_context;
...
for (;;)
{
try
{
io_context.run();
break; // run() exited normally
}
catch (my_exception& e)
{
// Deal with exception as appropriate.
}
}
提交任意自定义任务
通过调用自由函数: boost::asio::dispatch, boost::asio::post, boost::asio::defer实现任务提交,例如
void my_task()
{
...
}
...
boost::asio::io_context io_context;
// Submit a function to the io_context.
boost::asio::post(io_context, my_task);
// Submit a lambda object to the io_context.
boost::asio::post(io_context,
[]()
{
...
});
// Run the io_context until it runs out of work.
io_context.run(); @endcode
阻止io_context退出
在一些应用场景中,io_context对象需要在无任何任务时返回,例如io_context可能运行的背景线程,并且,背景线程可能在任何异步操作提交前被执行,通过创建boost::asio::executor_work_guard<io_context::executor_type>类型对象保持run()在无任何任务时保持不退出,例如:
boost::asio::io_context io_context;
boost::asio::executor_work_guard<boost::asio::io_context::executor_type>
= boost::asio::make_work_guard(io_context);
boost::asio::executor_work_guard<boost::asio::io_context::executor_type>类型的work对象的stop() 和 reset()
(1) 调用stop()关闭io_context,此时,run()函数将丢弃未完成的操作和不保证ready handlers被配发
(2) 调用reset()关闭io_context, 将保证全部操作和handler被正常地结束
boost::asio::io_context io_context;
boost::asio::executor_work_guard<boost::asio::io_context::executor_type>
= boost::asio::make_work_guard(io_context);
...
work.reset(); // Allow run() to exit.