Является ли ftruncate () асинхронным? - PullRequest
1 голос
/ 06 февраля 2012

Я пытаюсь написать класс на C ++, который обеспечивает средство атомарного добавления файла, даже в случае сбоя питания в середине записи.

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

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

К сожалению, похоже, что ftruncate () асинхронный.На практике, даже если я вызываю fflush () и fsync () после ftruncate, я вижу, что журнал увеличивается до сотен байтов при выполнении большого количества записей.Это всегда в конечном итоге заканчивается на 0, но я ожидал увидеть его всегда либо размером 0, либо размером 8.

Можно ли сделать ftruncate полностью синхронным?Или есть лучший способ использовать журнал?

1 Ответ

6 голосов
/ 06 февраля 2012

ftruncate() не изменяет смещение записи дескриптора файла в файле.Если вы оставляете файл открытым и записываете следующую длину после вызова ftruncate(), то происходит смещение файла, которое все еще увеличивается.Когда вы пишете, он сбрасывает длину файла в смещение, а затем записывает туда ваши байты.

Вероятно, вы хотите позвонить lseek(fd, 0, SEEK_SET) после вызова ftruncate(), чтобы следующийзапись в файл будет происходить в начале файла.

...