Linux平台上用于检查其实例的进程(C ++应用程序)尚未运行的最佳方法是什么?
答案 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执行此操作。它比使用文件锁更安全。