Есть ли более быстрый способ проверить, используется ли файл?

Есть ли более быстрый способ проверить, используется ли файл?

Я ищу функцию командной строки или функцию C, которая сообщит мне, открыт ли/используется ли файл кем-либо.

lsofи fuserговорят об этом, но они предоставляют много другой информации, из-за чего в некоторых ситуациях выполнение кода занимает до 300 мс (например, когда я использую этот код на MAC OS X, я разрабатываю для Linux и OS X) (у меня есть решение для Windows, которое выполняется за 5 мс, поэтому я пытаюсь найти что-то в Unix, что также будет очень быстрым и просто возвращает true или false, если файл используется)

решение1

Если вы используете это как блокировку, то она не будет работать ни как «ни» lsof, ни как fuser«предотвращать состояния гонки».

Базовый процесс, который lsofделает это, — это прочесывание всех процессов /proc/*/fsв поисках открытых файловых дескрипторов. Это займет время, независимо от того, что вы делаете.

Вы можете сделать это самостоятельно, но вряд ли это будет быстрее, поскольку вам придется проверять каждый открытый процесс в системе.

Если то, что вы делаете, требует времени, найдите другой способ это сделать.

  • Если вы управляете файлом через написанную вами программу, используйте файл блокировки.
  • Если вы запускаете какую-то команду, которая работает с файлом, посмотрите, какую документацию предлагает эта команда/программа, и посмотрите, не может ли она создать файл блокировки. Если это не удается, посмотрите, не может ли она создать файл со своим PID внутри него. Затем вы можете посмотреть на , /proc/<PID>/fsчтобы узнать, открыт ли ваш файл в данный момент или нет. Просмотр только одного процесса открытых файловых дескрипторов будет намного быстрее, чем сопоставление по всем из них.
  • В противном случае, чтобы помочь вам, мне понадобится больше информации о том, чем вы занимаетесь.

Вы дали больше информации в комментарии, что вы хотите определить, запущен ли Firefox на данной системе. Лучший способ сделать это — посмотреть файлы блокировки Firefox. Они хранятся вместоположения по умолчаниюуказано в вики Mozilla.

Например, в Linux ваша программа должна выполнять следующие действия:

  • откройте ~/.mozilla/firefox/каталог.
  • Вывести список всех каталогов, отфильтровав каталоги, заканчивающиеся на .default. (Я думаю, что все профили заканчиваются на .default, если не заходить в каждый каталог.)
  • В каждом каталоге выше найдите файл с именем lockили .parentlock. Если вы видите один или оба файла, Firefox открыт.

Этот алгоритм должен выполняться быстрее, чем то, что вы делаете в Windows в настоящее время.

решение2

TL;DR

Водин из ваших комментариев, вы заявляете:

Ну, моя точная ситуация такова: у меня есть путь к файлу. Он заблокирован, если запущен Firefox. Я хочу посмотреть, заблокирован он или нет, чтобы узнать, запущен ли Firefox.

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

Проверка состояния процесса

Более разумный способ найти PID заданного процесса — использоватьпгрепизпроцпспакет. Например:

$ pgrep -u $LOGNAME firefox
5671

Затем вы можете проверить состояние PID с помощьюпс:

$ ps 5671
  PID TTY      STAT   TIME COMMAND
 5671 ?        Sl   105:47 /usr/lib/firefox/firefox

или просто получите государственные флаги без всякого хлама:

$ ps -ho stat $(pgrep -u $LOGNAME firefox)
Sl

В моей системе однострочный код выше стабильно занимает всего 1,4 миллисекунды. Ваши результаты могут отличаться.

Коды состояний процесса

Раздел PROCESS STATE CODES в ps(1) подробно описывает, что означают различные флаги состояния. В Ubuntu 14.04 страница man гласит:

PROCESS STATE CODES
       Here are the different values that the s, stat and state output
       specifiers (header "STAT" or "S") will display to describe the state of
       a process:

               D    uninterruptible sleep (usually IO)
               R    running or runnable (on run queue)
               S    interruptible sleep (waiting for an event to complete)
               T    stopped, either by a job control signal or because it is
                    being traced
               W    paging (not valid since the 2.6.xx kernel)
               X    dead (should never be seen)
               Z    defunct ("zombie") process, terminated but not reaped by
                    its parent

       For BSD formats and when the stat keyword is used, additional
       characters may be displayed:

               <    high-priority (not nice to other users)
               N    low-priority (nice to other users)
               L    has pages locked into memory (for real-time and custom IO)
               s    is a session leader
               l    is multi-threaded (using CLONE_THREAD, like NPTL pthreads
                    do)
               +    is in the foreground process group

Связанный контент