Определите эффективную точность метки времени, возвращаемую "stat()"
Я пытаюсь определить эффективную точность st_mtim.tv_nsec
поле struct stat
в программном обеспечении, для конкретной директории / файловой системы.
Есть ли способ сделать это, который определяет точность времени модификации файловой системы (а не точность "наносекундной" библиотеки или точность кэша каталогов ОС)?
ДОБАВЛЕНО: Для некоторой справочной информации, это для инструмента, который обновляет некоторые файлы. Основной сценарий: "Если файл в первой группе файлов может быть новее, чем какой-либо файл во второй группе файлов, то использовать первую группу файлов для обновления второй группы файлов", а затем "Если файл в вторая группа файлов может быть новее любого файла в третьей группе файлов, а затем использовать вторую группу файлов для обновления третьей группы файлов".
У меня проблема в том, что при первом запуске инструмента (после изменения файла в первой группе) он обновит вторую группу файлов, а затем обновит третью группу файлов (что является правильным поведением); но во время второго запуска инструмента (когда ничего не изменилось) вторая группа файлов и третья группа файлов будут иметь одинаковые временные метки, поэтому он должен предполагать, что файл в третьей группе может быть новее, и он будет обновляться третья группа файлов без причины.
Чтобы исправить начальную проблему, я ввел задержку ("nanosleep();") перед обновлением третьей группы файлов; так что при следующем запуске инструмента третья группа файлов будет немного старше. Это позволяет избежать ненужных обновлений.
Конечно, все не так просто - существует произвольное количество "групп файлов", которые взаимозависимы (не только 3 группы).
Это подводит меня к моей текущей проблеме - для некоторых файловых систем точность отметки времени составляет всего 2 секунды, а необходимая задержка "наихудшего случая" огромна (например, она составляет как минимум 60 секунд задержек для 31 уровня " группы файлов "). Для большинства файловых систем временные метки гораздо точнее, и большое количество потерянного времени может исчезнуть. Конечно, инструмент должен быть "максимально переносимым", и я не могу сделать никаких предположений относительно точности отметки времени (было бы очень легко, если бы я знал, что файловая система всегда будет ext4 или что-то в этом роде),
3 ответа
Насколько я знаю, это невозможно сделать.
Единственный практический обходной путь - позволить конечному пользователю настроить его так, как ему удобно.
Примечание: я попытался найти способ сам, и спросил здесь и несколько других мест (в основном IRC-каналы для C и POSIX); и никто (включая меня) не смог найти способ сделать это.
Согласно этой ссылке OpenGroup,
Разрешение временных меток файлов в файловой системе определяется реализацией, но не должно быть грубее, чем разрешение в одну секунду. Три метки времени должны всегда иметь значения, которые поддерживаются файловой системой. Всякий раз, когда любая из временных меток файла должна быть установлена на значение V в соответствии с правилами предыдущих параграфов этого раздела, реализация должна немедленно установить для временной метки самое большое значение, поддерживаемое файловой системой, которое не превышает V.
Таким образом, вам гарантировано, что это будет не менее одной секунды.
Также, согласно этой справочной странице Linux по stat (2):
Начиная с ядра 2.5.48, структура stat поддерживает наносекундное разрешение для трех полей временных меток файла.
Linux или Windows не являются ОСРВ (операционными системами реального времени), и информация такого типа может быть не более 100 мс, обычно +-10 мс, насколько я помню, это был стандартный временной интервал планировщика.
Я не в курсе этой информации, но я почти уверен, что так оно и есть.
РЕДАКТИРОВАТЬ
Текущая реализация nanosleep() основана на обычном механизме таймера ядра, который имеет разрешение 1/ Гц с (см. Время (7)). Поэтому nanosleep() всегда делает паузу как минимум на указанное время, однако это может занять до 10 мс дольше, чем указано, до тех пор, пока процесс снова не будет запущен. По той же причине значение, возвращаемое в случае доставленного сигнала в *rem, обычно округляется до следующего большего кратного 1/ Гц с.