Может ли запуск нескольких асинхронных операций чтения / записи в одном потоке повредить данные? - PullRequest
6 голосов
/ 21 мая 2011

Я использую асинхронный ввод / вывод, потому что он не блокирует вызывающий поток и выполняет потоковые вещи за кулисами.Если я вызову несколько асинхронных операций, таких как BeginWrite (), в одном потоке, нужно ли мне беспокоиться о том, что содержимое буфера данных смешано вместе?

Давайте предположим, что я хочу отправить 3 буфера:

Buffer1: 1111111111
Buffer2: 2222222222
Buffer3: 3333333333

Я не против, если буферы отправляются в неправильном порядке, поэтому

333333333311111111112222222222

в порядке, но возможно ли, чтобы содержимое буфера полностью смешалось?

122213121212122333313111223333

PS: Я на 100% уверен, что кто-то уже спросил это в какой-то форме ...

Ответы [ 2 ]

8 голосов
/ 21 мая 2011

Зависит от реализации Stream.Например, сокеты поддерживают несколько перекрывающихся запросов как для чтения, так и для записи, как и файловый API.Они гарантируют согласованность каждой операции (без чередования содержимого), а также порядок операций: например, при чтении через сокет полученные байты будут помещены в буферы, размещенные в размещенном порядке.Если бы эти гарантии не были предоставлены, было бы невозможно написать высокопроизводительное сетевое приложение, так как перекрывающиеся Посылки желательны , но перекрывающиеся Получения фактически необходимы для высокопроизводительного сетевого ввода-вывода.Это поведение описано во многих статьях, в том числе в «хороших» Windows Sockets 2.0: создание масштабируемых приложений Winsock с использованием портов завершения , и задокументировано в MSDN Перекрываемый ввод / вывод :

Операции отправки и получения могут перекрываться.Функции приема могут быть вызваны несколько раз для отправки буферов приема при подготовке к входящим данным, а функции отправки могут быть вызваны несколько раз, чтобы поставить в очередь несколько буферов для отправки.Обратите внимание, что хотя серия перекрывающихся буферов отправки будет отправлена ​​в указанном порядке, соответствующие индикации завершения могут появляться в другом порядке.Аналогично, на принимающей стороне буферы будут заполняться в том порядке, в котором они поставляются, но индикации завершения могут появляться в другом порядке.

Не удивительно, что те же гарантии переносятся на управляемую сторонумир, например.NetworkStream класс:

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

При этом случайное выбрасывание асинхронных операций чтения и записи в поток приведет к хаосу довольно быстро.Приложения должны тщательно согласовывать порядок, в котором потоки представляют операции, чтобы порядок был детерминированным.Обычно это означает ведение учета в (синхронизированном) списке с особым вниманием к выполнению вызова асинхронной операции , в то время как удерживает блокировку синхронизации.

Последнее замечание: все эти асинхронные API-интерфейсы особо отмечают, что порядок завершение не обязательно соответствует порядку отправки.

0 голосов
/ 21 мая 2011

Нет, файловые потоки не поддерживают несколько одновременных операций ввода-вывода.Файловая система Windows не справляется с этим хорошо.Это почти наверняка вызовет исключение.

Редактировать:

Синхронизация и перекрывающийся ввод и вывод , кажется, указывает, что файловая система будет правильно обрабатывать несколько перекрывающихся запросов ввода-вывода.Мой плохой.

Однако не пытайтесь делать одновременные синхронные записи на FileStream. Это вызывает исключение.

...