Czy istnieje szybszy sposób sprawdzenia, czy plik jest w użyciu?

8

Szukam funkcji wiersza polecenia lub funkcji c, która poinformuje mnie, czy plik jest przez coś otwarty / używany.

lsofi fusermówię to, ale zawierają wiele innych informacji, które w niektórych sytuacjach powodują nawet do 300 ms (np. kiedy używam tego kodu w systemie Mac OS X, pracuję dla systemu Linux i OS X) (mam okno rozwiązanie, które zajmuje 5ms, więc próbuję znaleźć coś w Uniksie, które również jest bardzo szybkie i po prostu zwraca true lub false, jeśli plik jest w użyciu)

Noitidart
źródło

Odpowiedzi:

9

Jeśli używasz tego jako blokady, to nie będzie działać jak żaden lsoflub fuserzapobiec warunki wyścigu.

Podstawowym procesem lsofjest przeszukiwanie wszystkich procesów w /proc/*/fsposzukiwaniu otwartych deskryptorów plików. To zajmie trochę czasu bez względu na to, co robisz.

Możesz to zrobić samodzielnie, ale prawdopodobnie nie będzie to szybsze, ponieważ musisz sprawdzać każdy otwarty proces w systemie.

Jeśli to, co robisz, ma krytyczne znaczenie dla czasu, wymyśl inny sposób.

  • Jeśli kontrolujesz plik za pomocą napisanego programu; użyj pliku blokady.
  • Jeśli uruchamiasz jakieś polecenie działające na pliku, sprawdź i zobacz, jaką dokumentację oferuje to polecenie / program i sprawdź, czy nie może utworzyć pliku blokującego. Jeśli to się nie powiedzie, sprawdź, czy nie można utworzyć pliku z jego identyfikatorem PID. Następnie możesz /proc/<PID>/fssprawdzić, czy plik jest obecnie otwarty, czy nie. Patrząc tylko na jeden proces, deskryptory otwartych plików będą znacznie szybsze niż mapowanie na wszystkie.
  • W przeciwnym razie, aby ci pomóc, potrzebuję więcej informacji na temat tego, co robisz.

Podałeś więcej informacji w komentarzu, który chcesz ustalić, czy Firefox działa w danym systemie. Najlepszym sposobem na to jest poszukiwanie plików blokujących Firefoksa. Są one przechowywane w domyślnych lokalizacjach określonych na wiki Mozilli.

Na przykład, na Linuksie, niech twój program wykona następujące czynności:

  • otwórz ~/.mozilla/firefox/katalog.
  • Wyświetl wszystkie katalogi, filtrując katalogi kończące się na .default. (Myślę, że wszystkie profile kończą się .default, jeśli nie tylko indeksowaniem do każdego katalogu).
  • W każdym katalogu powyżej wyszukaj plik o nazwie locklub .parentlock. Jeśli widzisz jeden lub oba pliki, Firefox jest otwarty.

Ten algorytm powinien działać szybciej niż to, co obecnie robisz w systemie Windows.

Nixeagle
źródło
Doskonała odpowiedź, dziękuję. Czy w ogóle można powiedzieć lsof i utrwalaczowi, aby sprawdził folder pid tylko wtedy, gdy jest to Firefox? To pomogłoby pominąć całą zawartość folderów oprócz folderów firefox (mam 3 oddzielne instancje, co oznacza, że ​​po prostu sprawdza 3 foldery, prawda?)
Noitidart
Plik jest zablokowany, ale nie mogę dowiedzieć się, jak sprawdzić, czy jest zablokowany. Udało się otworzyć do odczytu / zapisu. To takie dziwne. Próbowałem fcntl z c, ale zawsze zwraca -1 :(
Noitidart
3
@ Noitidart Jaki jest twój rzeczywisty problem, który próbujesz rozwiązać? Aby sprawdzić otwarte deskryptory plików dowolnego procesu, musisz znać jego PID. To zmienia się dla każdej instancji programu. Prostym sposobem na uzyskanie go „ręcznie” jest ps aux firefox. Weź te PID i sprawdź je w /proc/systemie plików.
nixeagle
Ach, dzięki, że to dobry pomysł ps aux firefox. Moja dokładna sytuacja brzmi: mam ścieżkę do pliku. Jest zablokowany, jeśli Firefox jest uruchomiony. Chcę sprawdzić, czy jest zablokowany, czy nie powiedzieć, czy Firefox jest uruchomiony.
Noitidart
1
@Noitidart Zredagowałem swój komentarz, aby uwzględnić sposób wykrywania firefox poprzez sprawdzenie plików blokujących. Możesz powtórzyć ten proces na wszystkich systemach.
nixeagle
1

TL; DR

W jednym ze swoich komentarzy stwierdzasz:

Moja dokładna sytuacja brzmi: mam ścieżkę do pliku. Jest zablokowany, jeśli Firefox jest uruchomiony. Chcę sprawdzić, czy jest zablokowany, czy nie powiedzieć, czy Firefox jest uruchomiony.

Twoje pierwotne pytanie dotyczące plików blokujących wydaje się być daleką drogą, gdy istnieją łatwiejsze sposoby, aby dowiedzieć się, czy Firefox działa dla danego użytkownika i sprawdzić jego stan procesu.

Badanie stanu procesu

Bardziej sensownym sposobem znalezienia PID danego procesu jest użycie pgrep z pakietu procps . Na przykład:

$ pgrep -u $LOGNAME firefox
5671

Następnie możesz sprawdzić stan PID za pomocą ps :

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

lub po prostu zdobądź flagi stanu bez żadnych innych cruft:

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

Jeden z moich systemów, powyższa linijka konsekwentnie zajmuje tylko 1,4 milisekundy. Twój przebieg może się różnić.

Przetwarzaj kody stanu

Sekcja KODY STANU PROCESU ps (1) szczegółowo opisuje znaczenie różnych flag stanu. W Ubuntu 14.04 strona podręcznika mówi:

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
CodeGnome
źródło
1
Problem polega na tym, że musi wiedzieć, w którym firefoxie sesyjnym jest obecnie. W systemie Linux po prostu szukasz ~/.mozilla/firefox/*/lock. Następnie możesz zidentyfikować sesję, patrząc na nazwę katalogu nadrzędnego każdego pliku blokady. Na innych platformach to nie działa. Nasz czat mówi więcej o tym, jak uruchomić go na Macach (co jest trochę nieistotne dla Ubuntu, ale masz go). Aby być uczciwym, naprawdę powinien zaktualizować pytanie, aby było bardziej szczegółowe. : P
nixeagle