有没有更快的方法来检查文件是否正在使用?


8

我正在寻找一个命令行函数或c函数,该函数可以让我知道某个文件是否已打开/正在被某人使用。

lsoffuser确实说明了这一点,但是它们提供了很多其他信息,在某些情况下(例如,当我在MAC OS X上使用此代码时,我正在为Linux和OS X进行开发)会导致长达300毫秒的时间(我有一个Windows需要5毫秒的解决方案,因此我试图在Unix中查找也非常快的内容,如果正在使用文件,则返回true或false)


Answers:


9

如果您正在使用这个作为一个锁,它不会因为工作没有lsoffuser防止竞争条件。

这样lsof做的基本过程是遍历所有/proc/*/fs寻找打开文件描述符的过程。无论您做什么,这都需要时间。

您可以自己执行此操作,但是它可能不会更快,因为您必须检查系统上的每个打开的进程。

如果您的工作时间紧迫,请找出另一种方法。

  • 如果通过编写的程序控制文件;使用锁定文件。
  • 如果您正在运行对文件进行操作的某些命令,请查看并查看该命令/程序提供的文档,并查看它是否不能创建锁定文件。失败了,看看它是否无法创建一个带有PID的文件。然后,您可以查看/proc/<PID>/fs文件当前是否打开。仅查看一个进程,打开文件描述符比在所有进程中进行映射要快得多。
  • 否则,为了帮助您,我将需要有关您正在做的事情的更多信息。

您在注释中提供了更多信息,以便确定Firefox是否在给定系统上运行。最好的方法是查找Firefox的锁定文件。这些存储在Mozilla Wiki上指定的默认位置

例如,在Linux上,让您的程序执行以下操作:

  • 打开~/.mozilla/firefox/目录。
  • 列出所有目录,过滤以结尾的目录.default。(我认为所有配置文件都以结束.default,即使不只是爬到每个目录中。)
  • 在上面的每个目录中,查找是否存在名为lock或的文件.parentlock。如果您看到一个或两个文件,则表明Firefox已打开。

该算法的执行速度应该比您当前在Windows上执行的速度更快。


出色的回答,谢谢。无论如何,是否告诉lsof和热熔器仅检查Firefox的pid文件夹?这将使其跳过除firefox文件夹之外的所有文件夹内容(我有3个单独的实例,这意味着它仅检查3个文件夹对吗?)
Noitidart 2014年

该文件已锁定,但我不知道如何测试其是否已锁定。它已成功打开以进行读取/写入。太奇怪了 我从c尝试了fcntl,但它始终返回-1 :(
Noitidart 2014年

3
@Noitidart您要解决的实际问题是什么?为了查找任何进程的打开文件描述符,您必须知道其PID。这对于程序的每个实例都会更改。一种简单的“手动”获取方法是使用ps aux firefox。取得这些PID,并在/proc/文件系统中查找它们。
nixeagle14年

啊,谢谢,那是个好主意ps aux firefox。好吧,我的确切情况是:我有文件的路径。如果Firefox正在运行,它将被锁定。我想看看它是否被锁定,或者说Firefox是否正在运行。
Noitidart 2014年

1
@Noitidart我已经编辑了评论,包括如何通过查看锁定文件来检测Firefox。您可以在所有系统上重复此过程。
nixeagle 2014年

1

TL; DR

您的评论之一中,您声明:

好吧,我的确切情况是:我有文件的路径。如果Firefox正在运行,它将被锁定。我想看看它是否被锁定,或者说Firefox是否正在运行。

关于锁文件的最初问题似乎很漫长,因为有更简便的方法可以查找给定用户的Firefox是否正在运行,并检查其进程状态。

检查过程状态

找到一个给定的进程的PID一个更明智的方法是使用p纤epprocps的包。例如:

$ pgrep -u $LOGNAME firefox
5671

然后,您可以使用ps检查PID的状态:

$ 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
nixeagle14年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.