Почему `aio_write` запрещает одновременный доступ к буферу? - PullRequest
0 голосов
/ 04 июня 2018

Справочная страница Linux для aio_write говорит

Записываемая область буфера не должна иметь доступ во время операции или неопределенные результатыможет произойти.

Мой акцент на «доступ», который строго интерпретируется, не только сохраняет в буфере, но и загружает из буфера.

Man-страница в Mac OSX говорит:

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

Это звучит немного более разумно;буфер может быть прочитан, но не изменен.Последствия нарушения все еще остаются неопределенными.

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

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

Мой вопрос: что могло бы на самом деле, разумно произойти, учитывая системы и оборудование, которое у нас есть?Я предполагаю, что язык оставлен намеренно неопределенным, чтобы не ограничивать будущие реализации.

Ответы [ 2 ]

0 голосов
/ 06 июня 2018

Linux, BSD (MacOS - разновидность BSD), POSIX говорят разные вещи.

POSIX говорит:

Для любого системного действия, которое изменяет пространство памяти процесса во время асинхронногоОперации ввода-вывода выдаются из-за изменения диапазона адресов, результат этого действия не определен.

Руководство по Linux кажется более ограничительным, две возможности:

  1. Это вопросинтерпретация.Автор может подумать о доступе для записи , но просто написал доступе ,
  2. Это может быть любой доступ , поскольку реализация может использовать любой механизм, который можетзапретить любой доступ (строгая блокировка или защита во время ввода-вывода).

BSD также говорит:

Если запрос успешно поставлен в очередь, значение iocb-_aio_offset можно изменитьво время запроса в качестве контекста, поэтому на это значение нельзя ссылаться после того, как запрос помещен в очередь

, таким образом, явно запрещает некоторые доступы на чтение (к структуре управления).

Как сказал Мартин в комментарии: Я не знаю, почему кто-то захочет получить доступ к структурам / буферам / с до уведомления о завершении ввода / вывода .Но это также слишком ограничительно: хорошо, это понятно для доступа для записи , но можно представить (хотя и не часто) сценарий, в котором вы хотите доступ на чтение к буферу во время ввода-вывода(запись содержимого фрейм-буфера во время его отображения - или тому подобное.)

0 голосов
/ 04 июня 2018

Мой вопрос заключается в том, что на самом деле могло бы произойти, учитывая имеющиеся у нас системы и оборудование?Я предполагаю, что язык оставлен намеренно расплывчатым, чтобы не ограничивать будущие реализации.

Внимательно взгляните на API:

int aio_write(struct aiocb *aiocbp);

Заметьте, что он не принимает указатель на const?Предупреждение совершенно ясно: после передачи параметра aiocbp в aio_write () данные принадлежат коду AIO до завершения операции.Вы можете прочитать данные, но как вы можете ожидать их состояния?Согласно API и спецификации, вы не можете ожидать ничего вообще.Даже наблюдаемое поведение может показаться совершенно случайным.Кроме того, AIO может заблокировать строки кэша для этого блока по соображениям производительности (согласованности), любые операции чтения из другого ядра могут повлиять на производительность всей системы.

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

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