代码之家  ›  专栏  ›  技术社区  ›  Jan Deinhard

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

  •  14
  • Jan Deinhard  · 技术社区  · 15 年前

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

    7 回复  |  直到 13 年前
        1
  •  20
  •   Andrew Aylett    15 年前

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

    你可能会发现,有一些脚本可以帮助你做到这一点。 start-stop-daemon 有用的方法是:它可以使用PID文件,甚至可以全局检查是否存在可执行文件。它是专门为这项任务设计的,并且是为了帮助人们正确地完成任务而编写的。

        2
  •  5
  •   Benoît photo_tom    15 年前

    使用 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
    }
    
        3
  •  3
  •   Delan Azabani    15 年前

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

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

    如果不这样做:

    • 为执行上述操作之一的程序创建一个启动器包装器
        4
  •  2
  •   Vaibhav    15 年前

    我不知道您的确切要求是什么,但我有一个类似的要求;在这种情况下,我从shell脚本(它是一台HP-UX机器)启动了我的守护程序,在启动守护程序之前,我检查了同名的exec是否已经在运行。如果是的话,那就不要重新开始。

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

        5
  •  2
  •   Bart van Ingen Schenau    15 年前

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

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

        6
  •  0
  •   Daniel Voina    15 年前

    有一个PID文件,在启动时执行 'kill -0 <pid>' . 其中是从文件中读取的值。如果回答是!=0,则守护进程不活动,您可以重新启动它。

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

        7
  •  -1
  •   Ezra    13 年前

    我认为我的解决方案是最简单的:

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

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