Linux программирование в примерах | страница 91
Системы Unix осуществляют также опережающее чтение; поскольку чтение в большинстве случаев последовательное, операционная система после прочтения одного блока осуществляет чтение нескольких дополнительных последовательных блоков таким образом, что эта информация будет уже находиться в кэше, когда программа ее запросит. Если один и тот же файл читают несколько программ, они все получают преимущество, поскольку все получают свои данные из одной копии дисковых блоков файла в буферном кэше.
Все это кэширование, конечно, замечательно, но бесплатного обеда не бывает. В то время, пока данные находятся в буферном кэше и до того, как они будут записаны на диск, есть небольшое, но вполне реальное окно, в котором может случиться катастрофа; например, если выключат питание. Современные дисковые приводы обостряют эту проблему: у многих из них есть собственные внутренние буферы, поэтому при записи данных на диск они могут оказаться не записанными на носитель при выключении питания! Это может быть значительной проблемой для небольших систем, которые не находятся в информационном центре с контролируемым энергоснабжением или не имеют источников бесперебойного питания (UPS).[50]
Для большинства приложений вероятность того, что данные в буферном кэше могут быть нечаянно потеряны, довольно низка. Однако, для некоторых приложений любой такой шанс неприемлем. Поэтому в системе Unix было введено понятие синхронного ввода/вывода, при котором программе гарантируется, что по возвращении из системного вызова данные безопасно записаны на физическое устройство хранения.
Флаг >O_DSYNC
гарантирует целостность данных; данные и любая другая информация, которую операционная система должна найти, записываются на диск до возвращения >write()
. Однако, вспомогательные данные, такие, как время модификации или доступа к файлу, могут быть не записаны на диск. Флаг >O_SYNC
требует, чтобы эти данные также были записаны на диск до возвращения >write()
. (Здесь тоже нет бесплатного обеда; синхронные записи могут серьезно повлиять на производительность программы, заметно ее снизив.)
Флаг >O_RSYNC
предназначен для чтения данных: если >read()
находит данные в буферном кэше, которые были назначены для записи на диск, функция не вернет эти данные до тех пор, пока они не будут записаны. Два других флага влияют на это: в частности, >O_SYNC
заставит >read()
ждать, пока не будут также записаны и вспомогательные данные.
ЗАМЕЧАНИЕ