Existe uma maneira mais rápida de verificar se um arquivo está em uso?

7

Estou procurando uma função de linha de comando ou função c que me informará se um arquivo está aberto / em uso por alguma coisa.

lsof e fuser dizem isso, mas eles fornecem muitas outras informações que resultam em até 300ms em algumas situações (como quando eu uso este código no MAC OS X, estou usando o Linux e OS X) (Eu tenho uma solução windows que leva 5ms, então estou tentando encontrar algo no Unix que também é muito rápido, e apenas retorna true ou false se o arquivo estiver em uso)

    
por Noitidart 23.09.2014 / 20:41

2 respostas

9

Se você estiver usando isso como bloqueio, não funcionará como lsof ou fuser para evitar condições de corrida.

O processo básico que lsof faz é percorrer todos os processos /proc/*/fs procurando por descritores de arquivos abertos. Isso vai levar tempo, não importa o que você faça.

Você pode fazer isso sozinho, mas provavelmente não será mais rápido, pois você precisa verificar cada processo aberto no sistema.

Se o que você está fazendo for crítico, descubra outra maneira de fazê-lo.

  • Se você controlar o arquivo por meio de um programa que você escreveu; use um arquivo de bloqueio.
  • Se você estiver executando algum comando que opera no arquivo, veja e veja a documentação que o comando / programa oferece e veja se ele não pode fazer um arquivo de trava. Caso contrário, veja se não pode fazer um arquivo com o seu PID dentro dele. Então você pode olhar para /proc/<PID>/fs para ver se seu arquivo está aberto ou não. Observar apenas um processo de descritores de arquivos abertos será muito mais rápido do que o mapeamento em todos eles.
  • Caso contrário, para ajudá-lo, necessitarei de mais informações sobre o que você está fazendo.

Você forneceu mais informações em um comentário que deseja determinar se o Firefox está sendo executado em um determinado sistema. A melhor maneira de fazer isso é procurar por arquivos de bloqueio do Firefox. Estes são armazenados em locais padrão especificados no wiki da Mozilla.

Por exemplo, no linux, faça o seu programa fazer o seguinte:

  • abra o diretório ~/.mozilla/firefox/ .
  • Listar todos os diretórios, filtrando os diretórios que terminam em .default . (Acho que todos os perfis terminam com .default , se não apenas rastreiam em todos os diretórios.)
  • Em cada diretório acima, procure a existência de um arquivo chamado lock ou .parentlock . Se você vir um ou ambos os arquivos, o Firefox está aberto.

Este algoritmo deve ser executado mais rapidamente do que o que você faz no Windows atualmente.

    
por nixeagle 23.09.2014 / 21:38
1

TL; DR

Em um de seus comentários , você declara:

  

Bem, minha situação exata é: eu tenho o caminho para um arquivo. Está bloqueado se o firefox estiver em execução. Quero ver se está bloqueado ou não para saber se o firefox está rodando.

Sua pergunta original sobre arquivos de travamento parece ser o caminho mais longo quando há maneiras mais fáceis de descobrir se o Firefox está sendo executado para um determinado usuário e para inspecionar seu estado de processo.

Examinando o estado do processo

Uma maneira mais sensata de encontrar o PID de um dado processo é usar o pgrep do pacote procps . Por exemplo:

$ pgrep -u $LOGNAME firefox
5671

Você pode então inspecionar o estado do PID com ps :

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

ou apenas pegue os flags de estado sem nenhum outro tipo de código:

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

Um meu sistema, o one-liner acima, leva apenas 1,4 milissegundos para ser concluído. Sua milhagem pode variar.

Códigos do estado do processo

A seção PROCESS STATE CODES do ps (1) detalha o significado dos diversos sinalizadores de estado. No Ubuntu 14.04, a página man diz:

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
    
por CodeGnome 24.09.2014 / 08:19