Boost :: Asio сокет Async_ * Strand - PullRequest
9 голосов
/ 29 июля 2011

Как выполнить async_ * операции над сокетом через цепочку? Я посмотрел на Timer.5 (примеры Boost / Asio), но они показывают только, как вызывать обработчик пользователя. Когда я async_write в сокет, в многопоточном приложении данные могут быть записаны поврежденными. А strand гарантирует, что ни один из этих обработчиков не будет выполняться одновременно.

Ответы [ 2 ]

4 голосов
/ 30 октября 2011

С Boost.Asio документы:

Класс io_service :: strand предоставляет возможность отправлять и отправлять обработчики с гарантией того, что ни один из этих обработчиков не будет выполнен одновременно.

Существует хороший пример из strand использования в Boost.Asio примерах.

strand гарантирует, что выполнение вашего обработчика будет синхронизировано. Это означает, что strand полезен, если ваш io_service выполняется из нескольких потоков. Это не связано с тем, как вы планируете свои задачи (обработчики).

strand не может помочь вам одновременно выполнять несколько операций чтения или записи через сокет, поскольку внутреннее выполнение чтения / записи не может выполняться одновременно, поэтому должна быть только одна активная операция чтения или записи в асинхронном режиме.

Для reads вы просто вызываете async_read, чтобы инициировать последовательность чтения, и снова вызываете ее из обработчика чтения после использования полученных данных. То же самое, что вы делаете в однопоточной среде.

Для writes, если есть одновременные производители (если несколько потоков предоставляют данные для записи в сокет), вам нужна параллельная очередь (например, усиление циклического буфера , ищите «Пример ограниченного буфера») , Ваша функция записи берет данные из этого буфера и async записывает их в сокет. Ваш обработчик записи вызывает вашу функцию записи.

3 голосов
/ 30 октября 2011

Когда я async_write() к сокету в многопоточных данных приложения может быть написано повреждено. И Strand гарантирует, что ни один из тех обработчики будут выполняться одновременно.

Если нескольким потокам необходимо записать данные в сокет, вам нужно будет обеспечить порядок данных. Это ясно указано в документации async_write() .

Программа должна убедиться, что поток не выполняет другую запись операции (такие как async_write, async_write_some потока функция, или любые другие составные операции, которые выполняют запись) до эта операция завершена.

Я предлагаю сохранить исходящую очередь сообщений, которая очень похожа на этот вопрос и мой ответ .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...