如何防止Linux程序/守护进程在给定时间内被执行多次的最佳方法?
最常见的方法是创建一个PID文件:定义一个文件存储路径(通常在/var/run内部)。在成功启动时,您需要将进程的PID写入该文件。当您决定是否要启动时,读取该文件并检查所引用的进程是否存在(或者如果存在,则不是您守护进程的实例:在Linux上,您可以查看/proc/$PID/exe
)。在关闭时,您可以删除该文件,但这不是严格必需的。
有一些脚本可供使用,您可能会发现start-stop-daemon
很有用:它可以使用PID文件,甚至只检查全局可执行文件的存在性。它正是为了这个任务而设计的,并且旨在帮助人们正确地完成这项工作。
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/scoped_ptr.hpp>
int main()
{
using boost::interprocess;
boost::scoped_ptr<shared_memory_object> createSharedMemoryOrDie;
try
{
createSharedMemoryOrDie.reset(
new shared_memory_object(create_only, "shared_memory", read_write));
} catch(...)
{
// executable is already running
return 1;
}
// do your thing here
}
如果您有代码访问权限(即正在编写代码):
返回1;
或者,返回1;
如果您没有访问权限:
application.pid
,用于获取独占锁,在应用程序结束时会被释放。 - mhitza我不知道你确切的要求是什么,但我有类似的需求;在那种情况下,我从一个Shell脚本启动了我的守护进程(这是一台HP-UX机器),在启动守护进程之前,我检查是否已经有同名的exec在运行。如果有,则不启动新的。
通过这种方式,我还能够控制进程实例的数量。
有一个pid文件,在启动时执行'kill -0 <pid>'
。其中<pid>是从文件中读取的值。如果响应!= 0,则守护程序未运行,您可能需要重新启动它
另一种方法是绑定到端口,并在第二次尝试启动守护进程时处理绑定异常。如果端口正在使用,则退出,否则继续运行守护进程。
我相信我的解决方案是最简单的:
(如果竞态条件是可能发生的情况,请不要使用它,但在任何其他情况下,这是一个简单而令人满意的解决方案)
#include <sys/types.h>
#include <unistd.h>
#include <sstream>
void main()
{
// get this process pid
pid_t pid = getpid();
// compose a bash command that:
// check if another process with the same name as yours
// but with different pid is running
std::stringstream command;
command << "ps -eo pid,comm | grep <process name> | grep -v " << pid;
int isRuning = system(command.str().c_str());
if (isRuning == 0) {
cout << "Another process already running. exiting." << endl;
return 1;
}
return 0;
}
flock
,以确保使用 pid 的进程确实属于您。 - Hasturkunstart-stop-daemon
或类似工具,则无法以此方式锁定文件。此外,即使您设法获得锁定,仍应检查文件中包含的PID,因此我不确定它对您有多大帮助。 - Andrew Aylett