Как предотвратить запуск программы Linux более одного раза? - PullRequest
14 голосов
/ 14 сентября 2010

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

Ответы [ 7 ]

20 голосов
/ 14 сентября 2010

Наиболее распространенным способом является создание файла PID: определите местоположение, куда будет помещен файл (обычно это / var / run).При успешном запуске вы напишите свой PID в этот файл.Принимая решение о запуске, прочитайте файл и убедитесь, что указанный процесс не существует (или, если он существует, что это не экземпляр вашего демона: в Linux вы можете посмотреть /proc/$PID/exe).При завершении работы вы можете удалить файл, но в этом нет особой необходимости.

Существуют сценарии, которые могут помочь вам в этом, вам может пригодиться start-stop-daemon: он может использовать файлы PID или даже просто проверять глобальносуществование исполняемого файла.Он предназначен именно для этой задачи и был написан, чтобы помочь людям сделать это правильно.

5 голосов
/ 14 сентября 2010

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

Более точная ссылка на то, что вам нужно, будет эта .

#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 голосов
/ 14 сентября 2010

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

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

Если вы этого не сделаете:

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

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

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

2 голосов
/ 14 сентября 2010

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

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

0 голосов
/ 25 июля 2012

Я считаю, что мое решение самое простое:

(не используйте его, если возможны гоночные условия, но в любом другом случае это простое и удовлетворительное решение)

#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;
}
0 голосов
/ 14 сентября 2010

Иметь pid файл и при запуске сделать 'kill -0 <pid>'. Где значение, прочитанное из файла. Если ответ! = 0, то демон не жив и вы можете перезапустить его

Другим подходом будет привязка к порту и обработка исключения привязки при второй попытке запустить демон. Если порт используется, выйдите, в противном случае продолжайте работу демона.

...