Чи є більш швидкий спосіб перевірити, чи використовується файл?


8

Я шукаю функцію командного рядка або функцію c, яка дозволить мені знати, якщо файл чимось відкритий / використовується.

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


Відповіді:


9

Якщо ви використовуєте це як замок, він не буде працювати , як ні lsofабо fuserзапобігти умови гонки.

Основний процес, який lsofполягає в тому, щоб пройти через всі процеси, які /proc/*/fsшукають відкриті дескриптори файлів. Це займе час, незалежно від того, що ви робите.

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

Якщо те, що ви робите, є критичним для часу, придумайте інший спосіб зробити це.

  • Якщо ви керуєте файлом через програму, яку ви написали; використовувати файл блокування.
  • Якщо ви виконуєте якусь команду, яка працює над файлом, подивіться, яку документацію пропонує команда / програма, і перевірте, чи не може вона зробити файл блокування. Якщо цього не зробити, подивіться, чи він не може створити файл із PID всередині нього. Потім ви можете подивитися, /proc/<PID>/fsчи ваш файл наразі відкритий чи ні. Дивлячись лише на один процес, дескриптори відкритих файлів будуть набагато швидшими, ніж відображення всіх.
  • Інакше для того, щоб допомогти вам, мені знадобиться більше інформації про те, що ви робите.

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

Наприклад, у програмі linux ваша програма зробить наступне:

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

Цей алгоритм повинен виконуватись швидше, ніж те, що ви робите в Windows зараз.


Відмінна відповідь дякую. Чи потрібно все-таки сказати lsof та fuser перевірити папку pid, якщо це firefox? Це дозволило б пропустити весь вміст папок, крім папок firefox (у мене є 3 окремі екземпляри, це означає, що він просто перевіряє 3 папки?)
Noitidart

Файл заблокований, але я не можу зрозуміти, як перевірити, чи його заблоковано. Це успішно відкривається для читання / запису. Це так дивно. Я спробував fcntl від c, але його завжди повертається -1 :(
Noitidart

3
@Noitidart Яку актуальну проблему ви намагаєтеся вирішити? Щоб шукати дескриптори відкритого файлу будь-якого процесу, ви повинні знати його PID. Це змінюється для кожного примірника програми. Простий спосіб отримати це "вручну" за допомогою ps aux firefox. Візьміть ці PID-адреси та знайдіть їх у /proc/файловій системі.
nixeagle

ах спасибі це гарна ідея ps aux firefox. Ну моя точна ситуація: я маю шлях до файлу. Він заблокований, якщо працює Firefox. Я хочу перевірити, заблоковано чи не, чи працює Firefox.
Noitidart

1
@Noitidart Я змінив свій коментар, щоб вказати, як виявити firefox, переглянувши файли блокування. Ви можете повторити цей процес у всіх системах.
nixeagle

1

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

1
проблема полягає в тому, що він повинен знати, на якому сеансі працює Firefox. На Linux, ви просто шукаєте ~/.mozilla/firefox/*/lock. Потім можна визначити сеанс, переглянувши ім’я батьківського каталогу кожного файлу блокування. На інших платформах це не працює. Наш чат детальніше розглядає, як змусити його працювати над Mac (що для ubuntu якось не має значення, але там у вас є). Для справедливості він дійсно повинен оновити питання, щоб бути більш конкретним. : P
nixeagle
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.