системный вызов read () делает копию данных вместо передачи ссылки - PullRequest
2 голосов
/ 19 апреля 2011

Системный вызов read() заставляет ядро ​​копировать данные вместо передачи буфера по ссылке. Меня спросили причину этого в интервью. Лучшее, что я мог придумать, было:

  1. Чтобы избежать одновременной записи в один и тот же буфер в нескольких процессах.
  2. Если процесс уровня пользователя попытается получить доступ к буферу, сопоставленному с областью виртуальной памяти ядра, это приведет к segfault.

Как оказалось, интервьюер не был полностью удовлетворен ни одним из этих ответов. Я был бы очень признателен, если кто-нибудь мог бы уточнить выше.

Ответы [ 3 ]

3 голосов
/ 19 апреля 2011

Реализация нулевого копирования будет означать, что процессу на уровне пользователя должен быть предоставлен доступ к буферам, используемым ядром / драйвером для чтения. Пользователь должен будет сделать явный вызов ядру, чтобы освободить буфер после того, как с ним покончили.

В зависимости от типа устройства, с которого производится чтение, буферы могут быть больше, чем просто область памяти. (Например, некоторые устройства могут требовать, чтобы буферы находились в определенной области памяти. Или они могли поддерживать запись только в фиксированную область памяти, которую им давали при запуске.) В этом случае сбой пользовательской программы " освободить эти буферы (чтобы устройство могло записать в них больше данных) может привести к тому, что устройство и / или его драйвер перестанут работать должным образом, что пользовательская программа никогда не должна делать

1 голос
/ 19 апреля 2011

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

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

0 голосов
/ 19 апреля 2011

Возможно, я был готов оспорить утверждение интервьюера.Буфер в вызове read() предоставляется пользовательским процессом и, следовательно, поступает из адресного пространства пользователя.Также не гарантируется выравнивание каким-либо особым образом относительно рамок страницы.Это делает сложным делать то, что необходимо для выполнения ввода-вывода непосредственно в буфер, т.е.сопоставьте буфер с адресным пространством драйвера устройства или подключите его для DMA.Однако в ограниченных обстоятельствах это может быть возможно.

Кажется, я помню, что подсистема BSD, используемая Mac OS X, используемая для копирования данных между адресными пространствами, имела оптимизацию в этом отношении, хотя я могу быть совершенно ошибочным.

...