Existe-t-il un moyen plus rapide de vérifier si un fichier est en cours d'utilisation?

8

Je recherche une fonction de ligne de commande ou une fonction c qui me fera savoir si un fichier est ouvert / utilisé par quelque chose.

lsofet fuserdites-le, mais ils fournissent beaucoup d'autres informations qui entraînent jusqu'à 300 ms dans certaines situations (comme lorsque j'utilise ce code sur MAC OS X, je devve pour Linux et OS X) (j'ai une fenêtre solution qui prend 5 ms, donc j'essaie de trouver quelque chose dans Unix qui est également très rapide, et renvoie juste vrai ou faux si le fichier est en cours d'utilisation)

Noitidart
la source

Réponses:

9

Si vous utilisez cela comme un verrou, il ne fonctionnera pas non plus lsofou fuseréviter que les conditions de course.

Le processus de base qui le lsoffait est de parcourir tous les processus à la /proc/*/fsrecherche de descripteurs de fichiers ouverts. Cela va prendre du temps, quoi que vous fassiez.

Vous pouvez le faire vous-même, mais il est peu probable que ce soit plus rapide car vous devez vérifier chaque processus ouvert sur le système.

Si ce que vous faites est critique en termes de temps, trouvez une autre façon de le faire.

  • Si vous contrôlez le fichier via un programme que vous avez écrit; utilisez un fichier de verrouillage.
  • Si vous exécutez une commande qui opère sur le fichier, regardez et voyez quelle documentation cette commande / programme offre et voyez si elle ne peut pas créer un fichier de verrouillage. À défaut, voyez s'il ne peut pas créer un fichier avec son PID à l'intérieur. Ensuite, vous pouvez regarder /proc/<PID>/fspour voir si votre fichier est actuellement ouvert ou non. En regardant un seul processus, les descripteurs de fichiers ouverts seront beaucoup plus rapides que le mappage entre tous.
  • Sinon, pour vous aider, je vais avoir besoin de plus d'informations sur ce que vous faites.

Vous avez donné plus d'informations dans un commentaire que vous souhaitez déterminer si Firefox fonctionne sur un système donné. La meilleure façon de procéder consiste à rechercher les fichiers de verrouillage de Firefox. Ceux-ci sont stockés dans des emplacements par défaut spécifiés sur le wiki Mozilla.

Par exemple, sur Linux, demandez à votre programme de faire ce qui suit:

  • ouvrez le ~/.mozilla/firefox/répertoire.
  • Liste tous les répertoires, en filtrant les répertoires se terminant par .default. (Je pense que tous les profils se terminent par .default, si ce n'est pas simplement explorer tous les répertoires.)
  • Dans chaque répertoire ci-dessus, recherchez l'existence d'un fichier nommé lockou .parentlock. Si vous voyez un ou les deux fichiers, Firefox est ouvert.

Cet algorithme devrait s'exécuter plus rapidement que ce que vous faites actuellement sur Windows.

nixeagle
la source
Excellente réponse merci. Est-il possible de dire à lsof et à l'unité de fusion de ne vérifier le dossier pid que s'il s'agit de Firefox? Cela lui ferait sauter tout le contenu des dossiers à l'exception des dossiers de Firefox (j'ai 3 instances séparées, ce qui signifie qu'il vérifie juste 3 dossiers, n'est-ce pas?)
Noitidart
Le fichier est verrouillé, mais je ne sais pas comment tester s'il est verrouillé. Il s'ouvre avec succès en lecture / écriture. Il est tellement bizarre. J'ai essayé fcntl de c mais il revient toujours -1 :(
Noitidart
3
@Noitidart Quel est votre problème réel que vous essayez de résoudre? Pour rechercher les descripteurs de fichiers ouverts d'un processus, vous devez connaître son PID. Cela change pour chaque instance du programme. Un moyen simple de l'obtenir "manuellement" est d'utiliser ps aux firefox. Prenez ces PID et recherchez-les dans le /proc/système de fichiers.
nixeagle
ah merci c'est une bonne idée ps aux firefox. Eh bien ma situation exacte est: j'ai le chemin vers un fichier. Il est verrouillé si firefox est en cours d'exécution. Je veux voir si c'est verrouillé ou non pour dire si Firefox fonctionne.
Noitidart
1
@Noitidart J'ai modifié mon commentaire pour inclure comment détecter Firefox en regardant les fichiers de verrouillage. Vous pouvez répéter ce processus sur tous les systèmes.
nixeagle
1

TL; DR

Dans l' un de vos commentaires , vous déclarez:

Eh bien ma situation exacte est: j'ai le chemin vers un fichier. Il est verrouillé si firefox est en cours d'exécution. Je veux voir si c'est verrouillé ou non pour dire si Firefox fonctionne.

Votre question initiale sur les fichiers de verrouillage semble être le chemin à parcourir lorsqu'il existe des moyens plus faciles de savoir si Firefox fonctionne pour un utilisateur donné et d'inspecter son état de processus.

Examen de l'état du processus

Une façon plus judicieuse de trouver le PID d'un processus donné consiste à utiliser pgrep à partir du package procps . Par exemple:

$ pgrep -u $LOGNAME firefox
5671

Vous pouvez ensuite inspecter l'état du PID avec ps :

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

ou obtenez simplement les drapeaux de l'État sans autre cruauté:

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

Un mon système, le one-liner ci-dessus ne prend systématiquement que 1,4 millisecondes pour terminer. Votre kilométrage peut varier.

Codes d'état de processus

La section PROCESS STATE CODES de ps (1) détaille la signification des différents drapeaux d'état. Sur Ubuntu 14.04, la page de manuel indique:

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
la source
1
le problème est qu'il a besoin de savoir à quelle session firefox se trouve actuellement. Sur linux, il vous suffit de chercher ~/.mozilla/firefox/*/lock. Vous pouvez ensuite identifier la session en consultant le nom du répertoire parent de chaque fichier de verrouillage. Sur d'autres plateformes, cela ne fonctionne pas. Notre discussion explique plus en détail comment le faire fonctionner sur Mac (ce qui n'est pas pertinent pour Ubuntu, mais vous l'avez). Pour être juste, il devrait vraiment mettre à jour la question pour être plus précis. : P
nixeagle