Какой самый быстрый способ определения размера файла не равен нулю, не зная дескриптора файла? - PullRequest
2 голосов
/ 23 июня 2019

Чтобы кратко объяснить, зачем мне это нужно, я сейчас делаю обнаружение по stat(2).У меня нет контроля над файловым дескриптором (может быть использован другим потоком, поскольку мой код вводится для замены системных вызовов), поэтому я не могу использовать fstat(2) (что быстрее).Мне нужно делать эту проверку много раз, поэтому есть ли более быстрый способ сделать то же самое?Я проверяю один и тот же файл в разных процессах, которые не имеют родительских и дочерних отношений.

Ответы [ 2 ]

2 голосов
/ 23 июня 2019

Вы, вероятно, должны оценить его сами.

Я измерял

//Real-time System-time
272.58 ns(R)    170.11 ns(S)  //lseek
366.44 ns(R)    366.28 ns(S)  //fstat
812.77 ns(R)    711.69 ns(S)  //stat("/etc/profile",&sb)

на моем ноутбуке с Linux.Он немного колеблется между прогонами, но lseek обычно на кучу нс быстрее, чем fstat, но вам также нужен fd для него, а open ing довольно дорогой примерно при 1,6 мкс, так что stat, вероятно,лучший выбор для вашего случая.


Как заметил tom-karzes , stat должен зависеть от количества компонентов каталога в пути.Я попробовал это в длинном каталоге /foo/foo/.../foo PATH_MAX, и там я получаю 80µs.

0 голосов
/ 25 июня 2019

Наиболее эффективный подход, зная файловую систему, в которой вы ищете, состоит в том, чтобы открыть связанное блочное устройство и выполнить поиск (блок за блоком) таблицы инодов, а также проверить фактический размер по находящимся там инодам (откройте блочное устройство, поэтому вы получаете иноды из образов в памяти, а не с диска). Это позволяет вам быстро и просто получить все inode файловой системы нулевой длины. Недостатком является то, что вам сначала нужно получить информацию о файловой системе, а затем получить прямой доступ к блочному устройству, что обычно запрещено для процесса без полномочий root. После этого вам нужно выполнить поиск файловой системы, чтобы получить имена задействованных файлов, на тот случай, если вам нужно что-то сделать с этими файлами.

Кстати, ваше предположение о том, что не может использовать fstat(2) в дескрипторе общего файла с другим потоком, неверно , так как системный вызов stat работает с дескриптором открытого файла и не ' ничего не делать с файлом - он неблокирующий - и система гарантирует, что индекс заблокирован при доступе к структуре статистики.

Подход с использованием lseek(2) в этом случае недопустим, потому что он фактически перемещает указатель файла в конец файла, а затем обратно в сохраненное место, и для этого требуется два системных вызова, чтобы сделать и отмените ход , и существует множество сценариев гонки, которые могут произойти, если другой поток использует другой системный вызов (делает write(2), между двумя), пока у вас есть указатель файла в другом месте.

Unix (включая все системы posix linux, bsd и т. Д.) Гарантирует, что неблокирующий системный вызов (как stat(2)) является атомарным по своей природе, блокируя inode файла во время выполнения процесса (или потока) системный вызов. Так что никакой другой поток не может использовать файл, пока ваш системный вызов stat(2) получает данные. Даже при блокировке вызовов unix гарантирует, что для выполнения будет использован другой системный вызов, выполненный для того же дескриптора, и процессу / потоку придется ждать до завершения системного вызова stat(2).

Проблема в fstat(2) заключается в том, что он должен решить все элементы пути, пока не доберется до конечного индекса файла (это место, где хранится длина файла), и это делается один за другим. основа. До тех пор, пока он не доберется до последнего инода, не будет заблокирована последняя инода (на самом деле, он неизвестен, пока мы не доберемся до него, поэтому мы не можем заблокировать его, пока не закончим разрешение namei()), а затем он решается как оригинал stat(2).

ЗАКЛЮЧЕНИЕ

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

...