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

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

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

2 ответа

Решение

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

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

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

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

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

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

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

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

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

TL;DR

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

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

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

Изучение состояния процесса

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

$ pgrep -u $LOGNAME firefox
5671

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

$ 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 миллисекунды. Ваш пробег может варьироваться.

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

Раздел "КОДЫ СОСТОЯНИЯ ПРОЦЕССА" в ps(1) подробно описывает, что означают различные флаги состояния. На Ubuntu 14.04 на странице руководства написано:

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
Другие вопросы по тегам