Как предотвратить запуск программы Linux более одного раза?

каков наилучший способ предотвратить выполнение программы/демона Linux более одного раза в данный момент времени?

7 ответов


наиболее распространенным способом является создание 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
}

Если у вас есть доступ к коду (т. е. пишем):

  • создайте временный файл, заблокируйте его, удалите, когда закончите,return 1; Если файл существует, или,
  • список процессов, return 1; Если имя процесса в списке

Если вы не:

  • создайте оболочку запуска для программы, которая делает один из вышеперечисленных

Я не знаю, каково ваше точное требование, но у меня было аналогичное требование; в этом случае я запустил свой демон из сценария оболочки ( это была машина HP-UX), и перед запуском демона я проверил, работает ли exec с тем же именем. Если да, то не начинайте новую.

таким образом, я также смог контролировать количество экземпляров процесса.


Я думаю, что эта схема должна работать (а также устойчива к падениям):
Предварительное условие: существует PID-файл для вашего приложения (обычно в /var/run/)
1. Попробуйте открыть файл PID
2. Если он не существует, создайте его и напишите свой PID. Продолжить с остальной частью программы
3. Если он существует, прочитайте PID
4. Если PID все еще работает и является экземпляром вашей программы, затем exit
5. Если PID не существует или используется другой программой, удалите файл PID и перейдите к Шагу 2.
6. При завершении программы удалите файл PID.

цикл в шаге 5 гарантирует, что, если два экземпляра запущены одновременно, только один будет запущен в конце.


имейте PID-файл и при запуске сделайте 'kill -0 <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;
}