如何防止Linux程序多次运行?

时间:2010-09-14 07:42:16

标签: c++ c linux unix executable

防止Linux程序/守护程序在给定时间执行多次的最佳方法是什么?

7 个答案:

答案 0 :(得分:20)

最常见的方法是创建一个PID文件:定义文件的位置(内部/ var / run是常见的)。成功启动后,您将PID写入此文件。在决定是否启动时,请读取文件并检查以确保引用的进程不存在(或者如果它存在,则它不是守护程序的实例:在Linux上,您可以查看/proc/$PID/exe )。关闭时,您可以删除该文件,但这不是必需的。

有一些脚本可以帮助您完成此操作,您可能会发现start-stop-daemon很有用:它可以使用PID文件,甚至只是全局检查是否存在可执行文件。它专为这项任务而设计,旨在帮助人们做到正确。

答案 1 :(得分:5)

使用boost interprocess library创建将由进程创建的内存块。如果它已经存在,则意味着该进程的另一个实例。退出。

您需要的更精确的链接是this one

#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
}

答案 2 :(得分:3)

如果您有权访问该代码(即正在编写代码):

  • 创建一个临时文件,锁定它,完成时删除,return 1;如果文件存在,或者
  • 列出进程,return 1;如果进程名称在列表中

如果你不这样做:

  • 为执行上述
  • 之一的程序创建一个启动器包装器

答案 3 :(得分:2)

我不知道你的具体要求是什么,但我有类似的要求;在这种情况下,我从Shell脚本(它是HP-UX机器)启动了我的守护程序,在启动守护程序之前,我检查了同名的exec是否已经在运行。如果是;然后不要开始新的。

通过这种方式,我还能够控制进程的实例数。

答案 4 :(得分:2)

我认为这个方案应该有效(并且对于崩溃也很有效):
 前提条件:您的应用程序有一个PID文件(通常在/ var / run /中)  1.尝试打开PID文件
 2.如果它不存在,则创建它并将PID写入其中。继续执行程序的其余部分  3.如果存在,请读取PID
 4.如果PID仍在运行是程序的实例,则退出
 5.如果PID不存在或被其他程序使用,请删除PID文件并转到步骤2  6.程序终止时,删除PID文件。

步骤5中的循环确保,如果同时启动两个实例,则最后只会运行一个实例。

答案 5 :(得分:0)

有一个pid文件,并在启动时执行'kill -0 <pid>'。从文件中读取的值在哪里。如果响应是!= 0,则守护程序不活动,您可能会重新启动它

另一种方法是绑定到端口并在第二次尝试启动守护进程时处理绑定异常。如果端口正在使用,则退出,否则继续运行守护程序。

答案 6 :(得分:-1)

我相信我的解决方案最简单:

(如果比赛条件是可能的情况,请不要使用它,但在任何其他情况下,这是一个简单而令人满意的解决方案)

#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;
}