Строка определяется как строго последовательный вызов обработчиков событий (т.е. не одновременный вызов). Использование странд позволяет выполнять код в многоадресной программе без необходимости прямого блокировки (например, с использованием мутексов).
Строки могут быть либо косвенными, либо явными, о чем свидетельствуют следующие альтернативные подходы:
- Вызов io_service::run() из одной нити означает, что все обработчики событий выполняют в неявной полосе, из-за гарантии io_service, что обработчики используются только из-за внутренней работы ().
- Там, где есть одна цепь асинхронных операций, связанных с соединением (например, в полудуплексной реализации протокола, как HTTP), нет возможности параллельного выполнения обработчиков. Это неявная полоса.
io_service::strand
. Все объекты функции обработчика событий должны быть обернуты с помощью io_service::strand::wrap()
или иным образом размещены/отправлены через io_сервис::strand
объект.
В случае сочиненных асинхронных операций, таких как async_read()
или async_read_until()
, если обработчик завершения проходит через полосу, то все промежуточные обработчики также должны пройти через одну и ту же полосу. Это необходимо для обеспечения безопасного доступа к резьбе для любых объектов, которые распределены между звонителем и сложенной операцией (в случае async_read()
это розетка, которую звонящий может закрыть() для отмены операции). Это делается, имея функции крюка для всех промежуточных обработчиков, которые передают звонки на настраиваемый крючок, связанный с конечным обработчиком:
struct my_handler
{
void operator()() { ... }
};
template<class F>
void asio_handler_invoke(F f, my_handler*)
{
}
io_service::strand::wrap()
функция создает новый обработчик завершения, который определяет asio_handler_invoke
так, что объект функции выполняется через строку.
io_service::strand, tutorial Timer.5, HTTP-сервер 3 пример.