2

我正在使用 Objective-c 在 Mac 中编写命令行应用程序

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

有没有办法做到这一点?

4

3 回答 3

4

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

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

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

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

于 2012-05-31T00:19:30.327 回答
0

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

ps - A | grep <your executable name>

于 2012-05-30T12:00:09.630 回答
0

谢谢@abarnert。

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

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

我还没有将 pid 写入该文件,但在需要退出前一个实例时我会这样做(目前我还不需要它,但将来可能需要它)。我认为可以使用 PID 检索

int myPID=[[NSProcessInfo processInfo] processIdentifier];

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

看到答案,我会假设没有解决问题的直接方法。

于 2012-05-31T05:32:40.363 回答