2013-08-02 5 views
2

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

+0

Какой язык? Пока я рекомендую записать его в Erlang, так что вам не придется беспокоиться. ;) Если вы будете запускать только один экземпляр за раз, как это происходит, если он сработает, он может заблокировать другие экземпляры? –

+0

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

+0

Приложение читает файл, изменяет его и записывает обратно. Это не является одновременно безопасным, если одновременно выполняются два экземпляра. Кроме того, я беспокоюсь, что если экземпляр запускается, он захватывает блокировку, а затем выдает сбой, прежде чем освободить блокировку, тогда я не хочу, чтобы следующий экземпляр блокировался (после этого он запускается или уже ожидает блокировки выпущено) – John

ответ

2

Вы можете использовать средства блокировки файлов, предоставляемые Linux. Вы не указали язык, однако вы можете найти эту возможность почти везде в той или иной форме.

Вот простая идея, как это сделать в программе на языке C. Когда программа запускается, вы можете воспользоваться исключительной блокировкой блокировки для всего файла, используя системный вызов fcntl. Когда попытается запустить другой экземпляр приложений, он получит ошибку, пытающуюся заблокировать файл, что означает, что приложение уже запущено.

Вот небольшой пример того, как снять полную блокировку файла с помощью fcntl (эта функция предоставляет возможности для блокировки байтов диапазона, но когда длина равна 0, полный файл заблокирован).

struct flock lock_struct; 

    memset(&lock_struct, 0, sizeof(lock_struct)); 

    lock_struct.l_type = F_WRLCK; 
    lock_struct.l_whence = SEEK_SET; 
    lock_struct.l_pid = getpid(); 

    ret = fcntl(fd, F_SETLK, &lock_struct); 

Обратите внимание, что сначала вам нужно открыть файл, чтобы поместить замок. Это означает, что вам нужно иметь файл для использования для блокировки. Возможно, было бы полезно разместить его где-нибудь там, где это не вызовет каких-либо отвлекающих факторов/путаницы для других приложений.

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

Это только одна из идей. Я уверен, что есть другие способы.

+0

Итак, в приведенном выше примере fd является файловым дескриптором, который открывается до этого. Моя проблема в том, что fcntl, похоже, не блокирует. Я мог бы поместить цикл вокруг вызова fcntl 'while (! Ret)' и добавить спать там. Несмотря на то, что я работаю в своем конкретном случае, я надеялся на что-то большее, чем на самом деле, как на фактический перекрестный процесс-мьютекс. – John

+0

Я не уверен, зачем вам блокировать блокировку для вашего случая, но это может быть достигнуто путем замены 'F_SETLK' на' F_SETLKW'. –

+0

Если два человека пытаются запустить приложение одновременно, я хочу, чтобы оба экземпляра запускались - просто не в одно и то же время. – John

2

Обычный способ использования UNIX: ПИД-файлы.

Перед запуском процесса он проверяет, существует ли предварительно определенный файл - обычно /var/run/<process_name>.pid. Если обнаружено, это указывает на то, что процесс уже запущен, и этот процесс завершается.

Если файл не существует, это первый процесс запуска. Он создает файл /var/run/<process_name>.pid и записывает в него свой PID. Процесс отключает файл при выходе.

Update:

Для обработки случаев, когда демон врезался & оставленную файлом Pid, ​​дополнительные проверки могут быть сделаны во время запуска, если PID файл был найден:

  • Делает ps и убедитесь, что процесс с этим PID не существует
  • Если он существует, убедитесь, что его другой процесс
    • из указанного ps выхода
    • из /proc/$PID/stat
+1

Это не объясняет, как автоматически восстановить аварийный процесс. Файл все равно будет существовать, если процесс завершится ненормально. – nneonneo

Смежные вопросы