Главная » Архив материалов
Системный вызов write() выполняет лишь частичную запись с меныпей вероятностью,чем системный вызов readO делает частичное считывание. Помимоэтого, для системного вызова w r iteO не существует условия EOF. Что касаетсяобычных файлов, w r iteO гарантированно выполняет запрошенную операциюзаписи полностью, если только не происходит какая-либо ошибка.Следовательно, для обычных файлов нет необходимости реализовывать записьв цикле. Однако для других типов файлов, например сокетов, цикл можетпотребоваться, чтобы гарантировать, что все запрошенные байты действительнобудут записаны. Еще одно преимущество использования цикла состоит в том,что второй вызов w r iteO может вернуть ошибку, поясняющую, почему первыйвызов выполнил запись только частично (хотя, повторюсь, такая ситуациявстречается не часто). Вот пример реализации с циклом:ssize_t ret. nr.while (len
Просмотров: 474 | Добавил: admin | Дата: 28.03.2016 | Комментарии (0)

Когда файл fd открывается в режиме присоединения (при помощи флага0 APPEND), то запись начинается не с текущей позиции в файле, а с конца файла.Например, предположим, что два процесса записывают данные в один и тотже файл. В другом режиме, отличном от режима присоединения, если первыйпроцесс запишет данные в конец файла и потом то же самое сделает второйпроцесс, то позиция в файле для первого процесса уже не будет указывать наконец файла; она будет указывать в точку, отстающую от реального конца файлана длину данных, только что записанных вторым процессом. Это означает,что несколько процессов не могут присоединять данные к одному файлу без явнойсинхронизации, так как при этом они будут попадать в условия состязания.Режим присоединения позволяет избежать этой проблемы. Он гарантирует,что позиция в файле всегда устанавливается на конец файла, поэтому операциизаписи всегда присоединяют данные в конце файла, даже если их выполняютразные процессы. Можно представлять себе это так, как будто ... Читать дальше »
Просмотров: 543 | Добавил: admin | Дата: 28.03.2016 | Комментарии (0)

Когда файл fd открывается в режиме без блокировки (при помощи флага0 N0NBL0CK) и выполняется запись, которая в обычных условиях заблокирова-лась бы, системный вызов w r iteO возвращает значение -1 и присваивает переменнойеггпо значение EAGAIN. В такой ситуации запрос нужно повторить ещераз. С обычными файлами такая ситуация случается крайне редко.Прочие коды ошибокПрочие полезные значения еггпо включают в себя:EBADFУказанный файловый дескриптор недопустим или не открыт для записи.EFAULTУказатель в аргументе buf указывает за пределы адресного пространствапроцесса.EFBIGДанная операция записи сделала бы файл больше максимального допустимогоразмера для процесса или больше внутренних пределов реализации.EINVALУказанный файловый дескриптор соответствует объекту, не допускающемузапись.ЕЮПроизошла низкоуровневая ошибка.EN0SPCВ файловой системе, откуда взят данный дескриптор файла, недостаточносвободного пространства.EPIPEДанный файловый дескриптор связан с конвейером или сокетом, считывающаяст ... Читать дальше »
Просмотров: 584 | Добавил: admin | Дата: 28.03.2016 | Комментарии (0)

Если значение count превышает значение SSIZE_MAX, то результат вызова writeOне определен.Если выполнить write() со значением count, равным нулю, то вызов мгновенновернет значение 0.Поведение вызова write()Когда write() возвращает значение, это означает, что ядро скопировало данныеиз предоставленного буфера в буфер ядра, но нет никакой гарантии, что данныебыли записаны в указанное целевое местоположение. Действительно, этот вызоввозвращает значение слишком быстро, чтобы так действительно происходило.Несоответствие производительности процессоров и жестких дисков делалобы такое поведение мучительно очевидным.Вместо этого, когда приложение из пользовательского пространства выполняетсистемный вызов writeO, ядро Linux делает несколько проверок, а затемпросто копирует данные в буфер. Позже в фоновом режиме ядро собирает все«грязные» буферы, сортирует их оптимальным способом и записывает их содержимоена диск (этот процесс называется отложенной записью (writeback)).Благодаря этому с ... Читать дальше »
Просмотров: 546 | Добавил: admin | Дата: 28.03.2016 | Комментарии (0)

Еще один вопрос, связанный с отложенной записью, — это невозможностьпринудительно реализовывать упорядочение записи (write ordering). Хотя приложениеможет пытаться упорядочивать запросы на запись, чтобы эти данныеоказывались на диске в определенном порядке, ядро все равно меняет порядокзаписи так, как считает необходимым, — в основном учитывая соображенияпроизводительности. Обычно это превращается в проблему только в случаесистемных сбоев, так как в конечном итоге данные из всех буферов записываютсяна диск и все хорошо. Как бы то ни было, большая часть приложений никогдане заботится о порядке записи буферов на диск.Последняя проблема, связанная с отложенной записью, относится к сообщениямоб определенных ошибках ввода-вывода. Процессу, который выполнилзапрос на запись, невозможно сообщить ни о какой ошибке ввода-вывода, котораяпотенциально произойдет во время отложенной записи, например, о физическомсбое жесткого диска. Действительно, буферы совершенно не связаны спроцессами ... Читать дальше »
Просмотров: 552 | Добавил: admin | Дата: 28.03.2016 | Комментарии (0)

Хотя синхронизация ввода-вывода — это очень важная тема, не следует боятьсявопросов, связанных с отложенной записью. Буферизация записи обеспечиваетогромный выигрыш в производительности, и, следовательно, в любой операционнойсистеме, находящейся хотя бы на полпути к получению звания ?современная?, реализуется отложенная запись с использованием буферов. Тем неменее иногда в приложениях возникает необходимость контролировать момент,когда данные оказываются на диске. Для этого ядро Linux предоставляетнесколько параметров, позволяющих обменивать производительность на синхронностьопераций.fsync() и fdatasync()Самый простой способ гарантировать, что данные достигнут диска, — использоватьсистемный вызов fsync(), определенный в POSIX.lb следующим образом:finclude <unistd.h>int fsync (int fd);Вызов fsyncO гарантирует, что все грязные данные, соответствующие файлу,который указан при помощи дескриптора файла fd, записываются обратнона диск. Файловый дескриптор fd должен быть отк ... Читать дальше »
Просмотров: 396 | Добавил: admin | Дата: 28.03.2016 | Комментарии (0)

К счастью, данные в кэше жесткого диска должны фиксироваться на диске незамедлительно.В Linux также предусмотрен системный вызов fdatasyncO:finclude <unistd.h>int fdatasync (int fd);Этот системный вызов делает то же самое, что и fsyncO, но он ограничиваетсясбросом только данных. Вызов не гарантирует, что метаданные также синхронизируютсяс диском, и поэтому работает потенциально быстрее. Зачастуюэтого бывает достаточно.Обе функции применяются одинаково и очень просто:int ret:ret = fsync (fd):i f (ret
Просмотров: 484 | Добавил: admin | Дата: 28.03.2016 | Комментарии (0)

В случае успеха оба вызова возвращают значение 0. В случае сбоя оба вызовавозвращают -1 и присваивают переменной еггпо одно из следующих трехзначений:EBA0FУказанный файловый дескриптор является недопустимым или не открытдля записи.EINVALУказанный файловый дескриптор соответствует объекту, пе поддерживающемусинхронизацию.ЕЮВо время синхронизации произошла низкоуровневая ошибка ввода-вывода.Это говорит о реальной ошибке ввода-вывода, и именно здесь зачастую отлавливаютсятакие ошибки.Вызов fsyncO может легко завершиться ошибкой из-за того, что fsyncO нереализован в конкретной файловой системе, даже если fdatasyncO реализован.В параноидальных приложениях в случае, когда fsync( ) возвращает код ошибкиEINVAL, можно пробовать делать то же самое с использованием fdatasyncO. Например:if (fsync (fd)
Просмотров: 384 | Добавил: admin | Дата: 28.03.2016 | Комментарии (0)

Не такой оптимальный, но более масштабный консервативный системный вызовsync() обеспечивает синхронизацию всех буферов с диском:#include <unistd.h>void sync (void):У этой функции нет параметров, и она не возвращает никакое значение. Онавсегда завершается успешно, и возврат значения указывает на то, что все буферы— как с данными, так и с метаданными — были гарантированно записаны надиск1.Стандарты не требуют, чтобы вызов sync О ожидал, пока все буферы будутсброшены на диск, чтобы возвратить значение; они требуют только, чтобы вызовинициировал процесс фиксации всех буферов на диске. По этой причинечасто рекомендуется выполнять синхронизацию несколько раз, чтобы гарантировать,что все данные успешно оказались на диске. Linux, однако, дожидаетсяфиксации буферов. Таким образом, одного вызова sync О достаточно.Единственное реальное применение sync О можно найти в реализации утилитыsync(8). Для фиксации на диске данных для конкретных дескрипторовфайлов в приложениях следует и ... Читать дальше »
Просмотров: 467 | Добавил: admin | Дата: 28.03.2016 | Комментарии (0)

Очень часто в программах не проверяют возвращаемое значение вызова c lo se ( ).Если не выполнить такую проверку, то можно пропустить критическое условиеошибки, так как ошибки, связанные с отложенными операциями, могут не проявлятьсядовольно долго, а при помощи closeO их вполне можно отлавливать.Существует несколько возможных значений переменной еггпо, возвращаемыхв случае ошибки. Помимо EBADF (данный дескриптор файла недопустим),наиболее важное значение ошибки — это ЕЮ, указывающее на низкоуровневуюошибку ввода-вывода, возможно, не связанную с фактической операцией закрытия.Независимо от того, какая ошибка возвращается, дескриптор файла,если он допустим, всегда закрывается, а связанные с ним структуры данныхосвобождаются.Хотя POSIX допускает это, вызов closeO никогда не возвращает значениеEINTR. Разработчики ядра Linux лучше знают, что такая реализация не блещетсмыслом.Поиск за пределами конца файлаВызов lseekO можно применять также для перемещения указателя файла запределы файла ... Читать дальше »
Просмотров: 423 | Добавил: admin | Дата: 28.03.2016 | Комментарии (0)

« 1 2 ... 5 6 7 8 9 ... 17 18 »