检测另一个程序副本是否正在运行(*NIX专用)
一个巧妙的技巧是发送信号0来查看另一个进程是否正在运行。信号0实际上不会被发送,但kill会检查是否可以发送信号。请注意,这只有在您有权向该进程发送信号的情况下才有效。
此技术的实际用途是避免运行同一程序的多个副本。您以通常的方式将PID保存到文件中……然后在启动期间,您检查PID文件的值,并查看该进程当前是否存在。
这并非完全万无一失。在极少数情况下,不相关的程序可能具有相同的已回收PID。但是,另一个程序很可能不会接受来自您的程序的信号(除非您的程序是root)。
为了使其尽可能可靠,您希望您的程序在关闭时删除其PID文件(参见register_shutdown_function)。这样,只有当您的程序崩溃并且另一个程序碰巧使用相同的PID并且另一个程序愿意接受来自您的程序的信号时,您才会得到错误的结果。这将是极其罕见的情况。这也假设PID文件没有被篡改(所有依赖PID文件的程序都是如此……)。
也可以使用“ps x”来检测这一点,但是使用kill效率更高。
这是核心程序
$PrevPid = file_get_contents($PathToPidFile);
if(($PrevPid !== FALSE) && posix_kill(rtrim($PrevPid),0)) {
echo "错误:服务器已使用PID:$PrevPid运行\n";
exit(-99);
} else {
echo "正在启动服务器…";
}
嗯……如果您想要完全100%的可靠性以及效率。您可以做的是使用kill进行初始检查。如果它说没有运行,那么您就可以准备运行了。但是,如果kill说已经在运行,那么您可以使用
//您可以从$argv[0]获取$ProgramName
$Result = shell_exec('ps x | grep "' . $PrevPid . '" | grep "' . $ProgramName . '" | grep -v "grep"');
假设您的程序有权执行此操作。如果您执行该命令并返回空字符串,则另一个程序是使用已回收PID的冒名顶替者,您可以继续运行。
-- Erik