Estou procurando uma função de linha de comando ou função c que me informe se um arquivo está aberto/em uso por alguma coisa.
lsof
e fuser
conte isso, mas eles fornecem muitas outras informações que resultam em levar até 300 ms em algumas situações (como quando eu uso esse código no MAC OS X, estou desenvolvendo para Linux e OS X) (eu tenho um windows solução que leva 5ms, então estou tentando encontrar algo no Unix que também seja muito rápido e retorne verdadeiro ou falso se o arquivo estiver em uso)
Responder1
Se você estiver usando isso como um bloqueio, não funcionará como nenhum dos dois lsof
nem fuser
evitará condições de corrida.
O processo básico lsof
é percorrer todos os processos /proc/*/fs
em busca de 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 será necessário verificar todos os processos abertos no sistema.
Se o que você está fazendo exige tempo, descubra outra maneira de fazer isso.
- 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 qual documentação esse comando/programa oferece e veja se ele não consegue criar um arquivo de bloqueio. Caso contrário, veja se não consegue criar um arquivo com seu PID dentro dele. Então você pode verificar
/proc/<PID>/fs
se o seu arquivo está aberto ou não. Observar apenas os descritores de arquivos abertos de um processo será muito mais rápido do que mapear todos eles. - Caso contrário, para ajudá-lo, precisarei 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 os arquivos de bloqueio do Firefox. Estes são armazenados emlocais padrãoespecificado no wiki da Mozilla.
Por exemplo, no Linux, faça com que seu programa faça o seguinte:
- abra o
~/.mozilla/firefox/
diretório. - Liste todos os diretórios, filtrando os diretórios que terminam em
.default
. (Acho que todos os perfis terminam com.default
, se não apenas rastrearem 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 rápido do que o que você faz no Windows atualmente.
Responder2
DR
Emum de seus comentários, você afirma:
Bem, minha situação exata é: eu tenho o caminho para um arquivo. Ele 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 lockfiles parece um longo caminho quando existem maneiras mais fáceis de descobrir se o Firefox está sendo executado para um determinado usuário e de inspecionar o estado do processo.
Examinando o estado do processo
Uma maneira mais sensata de encontrar o PID de um determinado processo é usarpgrepdeprocpspacote. Por exemplo:
$ pgrep -u $LOGNAME firefox
5671
Você pode então inspecionar o estado do PID comobs::
$ ps 5671
PID TTY STAT TIME COMMAND
5671 ? Sl 105:47 /usr/lib/firefox/firefox
ou apenas obtenha as bandeiras do estado sem qualquer outro problema:
$ ps -ho stat $(pgrep -u $LOGNAME firefox)
Sl
Em meu sistema, o one-liner acima leva consistentemente apenas 1,4 milissegundos para ser concluído. Sua milhagem pode variar.
Códigos de estado de processo
A seção PROCESS STATE CODES do ps(1) detalha o que significam os vários sinalizadores de estado. No Ubuntu 14.04, a página de manual 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