在Linux上防止多个流程实例

时间:2010-06-03 08:42:30

标签: c++ linux process

Linux平台上用于检查其实例的进程(C ++应用程序)尚未运行的最佳方法是什么?

5 个答案:

答案 0 :(得分:5)

您可以使用文件和文件锁来实现这一目标,但是,请注意它并不完美,并且不要复制臭名昭着的Firefox错误,即使它还没有运行,它有时会拒绝启动。

它的基本逻辑是:

Invariant:
    File xxxxx will exist if and only if the program is running, and the
    contents of the file will contain the PID of that program.

On startup:
    If file xxxxx exists:
        If there is a process with the PID contained in the file:
            Assume there is some instance of the program, and exit
        Else:
            Assume that the program terminated abnormally, and
            overwrite file xxxx with the PID of this program
    Else:
        Create file xxxx, and save the current PID to that file.

On termination (typically registered via atexit):
    Delete file xxxxx

除了上面的逻辑之外,您还应该使用锁定的第二个文件来同步对PID文件的访问(即充当互斥锁以使其在进程级并发方面安全)。 / p>

答案 1 :(得分:5)

执行此操作的标准方法是在某处创建一个pid文件,通常包含程序的pid。

你不需要把pid放在那里,你可以放一个独占锁。如果你打开它进行读/写,并用LOCK_EX |来填充它LOCK_NB,如果文件已被锁定,它将失败。这是无竞争条件的,如果程序崩溃,锁将自动释放。

通常你想要按用户这样做,所以用户的主目录是放置文件的好地方。

如果它是守护进程,那么像/ var / run这样的地方会更好。

答案 2 :(得分:1)

迈克尔解决方案的一个相关替代方法是在已知位置(可能位于/ var / run或/ tmp下)创建目录,并使用系统调用的成功/失败作为确保互斥的机制。这是CVS多年来使用的相同的互斥技巧,因为目录创建在大多数(可能是所有)商品操作系统上都是原子的。在目录+ PID创建过程意外死亡且无法清理的情况下,PID文件仍然有用。此外,在检查现有目录+ PID是否有效时,我建议明确检查/proc/<PID>/exe符号链接以验证它是否指向您的可执行文件,而不是假设PID尚未被回收。

答案 3 :(得分:0)

对于桌面应用,检查是否为当前用户启动实例可能更为可行,这样两个用户就可以运行自己的实例。

您可以使用某些库(libunique(GTK +)或QtSingleApplication(Qt)),也可以自己动手。除了前面提到的pid-file之外,您还可以在用户主目录中的某个位置打开FIFO或UNIX域套接字。这样,您就可以与正在运行的实例进行通信,例如。引发运行实例的窗口或告诉运行实例打开新文件/ URI /无论如何。

答案 4 :(得分:-1)

您可以使用POSIX named semaphore执行此操作。它比使用文件锁更安全。