在Linux上防止多个进程实例

在Linux平台上进程(C ++应用程序)检查其实例的最佳方式是不是已经在运行了?

Solutions Collecting From Web of "在Linux上防止多个进程实例"

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

你不需要把pid放在那里,你可以放一个独占的锁。 如果你打开它来阅读/写作,并用LOCK_EX |将它植入 LOCK_NB,如果文件已经被锁定,将会失败。 这是免费的竞赛条件,锁定将自动释放,如果程序崩溃。

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

如果是守护进程,则类似/ var / run的地方会更好。

你可以使用文件和文件锁来实现这个功能,但是要注意它并不完美,不要复制臭名昭着的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文件的访问(即充当互斥体以使其在进程级别的并发性方面更安全)。

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

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

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

你可以使用一个POSIX命名的信号来做到这一点。 它比使用文件锁更安全。