Asio асинхронность и параллелизм - PullRequest
2 голосов
/ 16 декабря 2009

Я пишу некоторый код с boost asio, используя асинхронные TCP-соединения. Я должен признать, что у меня есть некоторые сомнения по этому поводу. Все это касается параллелизма. Вот некоторые из них:

  • Что произойдет, если я запускаю два или более async_write на одном сокете, не дожидаясь завершения первого? Будут ли перекрываться обработчики (и async_write) или asio обеспечивает сериализацию и синхронизацию?

    • Тот же вопрос, что и выше, с async_connect и async_read. Вообще безопасно ли вызывать эти функции из разных потоков (я не говорю об использовании разных буферов, это другая проблема ...).

Ответы [ 2 ]

2 голосов
/ 19 декабря 2009

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

asyncwrite () в конечном счете вызывает метод post () ioservice, который, в свою очередь, берет блокировку и помещает биты для записи в рабочую очередь, гарантируя, что биты не будут записаны с чередованием. Эти биты в конечном итоге будут записаны, и основная структура данных, в которой они хранятся (массив символов или что-то еще), должна оставаться действительной до тех пор, пока вы не получите обратный вызов, означающий, что запись завершена. Если вы используете ту же функцию обратного вызова, что и ваш обработчик завершения, у вас не будет возможности узнать, какая из двух записей привела к вызову этой функции, и если эта функция не выполняет потоковую обработку, поведение может быть неопределенным или неправильным. Популярный способ справиться с этой ситуацией - иметь экземпляр структуры, который является обработчиком завершения (просто перегрузите оператор ()): вы можете установить свойства структуры, чтобы обозначать, какой записи она соответствует, и затем обращаться к этим значениям, когда обработчик завершения называется.

Однако, при отсутствии разделяемой блокировки, вы не можете контролировать, какой из потоков фактически выполняет свой метод asyncwrite. На самом деле, даже если вы запускаете два потока и один поток немедленно вызывает asyncwrite, а другой спит в течение часа, а затем вызывает asyncwrite, вы все равно не уверены, что ОС не спланировала ваши потоки тупо и выполнила второй поток. позвони первым. (Пример патологический, но этот пункт универсален.)

Та же ситуация применима к асинхронным потокам. Вы, конечно, можете чередовать вызовы (т. Е. Выполнить один асинхронный вызов, а затем другой перед вызовом обработчика завершения), но нет гарантии, что он будет выполняться в том порядке, в котором вы собираетесь, без каких-либо внешних средств для обеспечения этого.

0 голосов
/ 16 декабря 2009

Если вы запустите две асинхронные операции в одном сокете, они могут выполняться в любом порядке. Пока они используют разные буферы, это «безопасно», в том смысле, что оно не будет аварийно завершаться, но такое поведение почти никогда не соответствует вашим ожиданиям.

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