如何检查app / binary的另一个实例是否已在运行

时间:2012-05-30 10:16:10

标签: objective-c macos osx-lion osx-snow-leopard command-line-tool

我正在使用Objective-c

在Mac上编写命令行应用程序

在应用程序开始时,我想检查同一应用程序的另一个实例是否已在运行。如果是,那么我应该等待它完成或退出当前实例或退出其他实例等。

有没有办法做到这一点?

3 个答案:

答案 0 :(得分:4)

标准的Unix解决方案是创建一个“运行文件”。启动时,如果不存在,则尝试创建该文件并将pid写入其中;如果确实存在,请从中读取pid,如果有正在运行的程序带有该pid和进程名称,则等待/退出/等等。

问题是,你把文件放在哪里,你怎么称呼它?

嗯,首先,您必须确定“已经运行”的含义。显然不是“世界上任何地方”,但它可以是“当前机器上的任何地方”到“当前桌面会话”中的任何内容。 (例如,如果用户A启动您的程序,暂停它,然后用户B出现并通过快速用户切换接管计算机,是否能够运行该程序?)

对于这个问题几乎任何合理的答案,都有一个明显的路径名模式。例如,在Mac上,/ tmp在系统范围内共享,而$ TMPDIR特定于给定的会话,因此,例如/tmp/${ARGV[0]}.pid是一种说“只有一个”的好方法在机器上复制,期间“,而$ {TMPDIR} / $ {ARGV [0]}。pid是说”每个会话只有一个副本“的好方法。

答案 1 :(得分:0)

执行此操作的简单但常见的方法是检查进程列表中是否有可执行文件的名称。

ps - A | grep <your executable name>

答案 2 :(得分:0)

谢谢@abarnert。

这就是我目前的实施方式。在main()的开头,我会检查二进制文件自己的目录中是否存在名为.lock的文件(我正在考虑将其移动到/ tmp)。如果是,则退出应用程序。

如果没有,它将创建该文件。 在应用程序结束时,.lock文件被删除

我还没有将pid写入该文件,但是在退出前一个实例时我将需要(因为我还不需要它,但可能在将来)。 我认为可以使用

检索PID
int myPID=[[NSProcessInfo processInfo] processIdentifier];

程序将由作为根守护程序运行的自定义计划程序调用。所以它将以root身份运行。

看到答案,我认为没有解决问题的直接方法。