Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Единственный экземпляр приложения  (Прочитано 9197 раз)
0 Пользователей и 1 Гость смотрят эту тему.
vbb
Гость
« : 18-08-2005 14:01 » 

Как под солярку/unix реализовать код, который помог бы избежать запуска нескольких экземпляров приложения?

Под win использовал именнованые мьютексы, под солярку/unix пока не знаю как реализовать....

Записан
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 18-08-2005 14:24 » 

Широко распространена техника записи pid в файл

При запуске проверять, есть ли файл /var/myapp.pid
Если нет, то создать файл и записать в него идентификатор текущего процесса. На выходе файл удалить.
Если есть, то прочитать из файла идентификатор процесса и проверить, есть ли такой процесс.  Далее можно сразу отваливаться.  Это не очень надёжно, но широко используется.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 18-08-2005 14:48 » 

Логичнее использовать /var/run/имя.pid или /var/lock/имя.pid , но жестких правил нет.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
vbb
Гость
« Ответ #3 : 18-08-2005 14:55 » 

каким образом эта схема обеспечивает блокировку вызова второго экземпляра приложения?
между открытием, записью, чтением и проверкой есть ли такой процесс пройдет уйма времени... может пройзоити обыкновенная гонка
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 18-08-2005 16:44 » 

vbb, пойди от обратного: отчего твое приложение будет столь быстро множиться? Это или кривая программа ее запускает, либо плохая мышь у пользователя. В остальных случаях вероятность столь синхронного запуска стремится к нулю.

Если тебе нужны более надежные способы, то используй fcntl() с F_SETLKW. Заблокировать файл сможет только одна программа.

Открой файл с O_CREAT, заблокируй и прочти - если пустой, то его создал ты - запиши в него свой pid и закрой его. Если файл не пуст, прочти pid и проверь наличие такого процесса. Если его нет, то запиши туда свой pid и считай что все ок. Коли нет - закрывай прогу.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 19-08-2005 09:24 » 

Да, RXL, ты прав, про /var я погорячился, обычно кладут в /var/run или /var/lock

В принципе, open + fcntl в сочетании с  F_SETLKW аналогично использованию именованных мутексов в винде.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
vbb
Гость
« Ответ #6 : 19-08-2005 12:53 » 

В принципе все замечательно, но столкнулся с такой проблемой:
 программа стартует, создает -
      if ( (f = open(name, O_RDWR | O_CREAT)) > 0 )
 и блокирует файл -
      mylock.l_type = F_WRLCK;
      if ( (fc = fcntl(f, F_SETLK, &mylock)) != -1 )
 после этого падает по exception (например деление на 0 Улыбаюсь )
 перезапуск программы выдает 'Permission denied' на open(), т.е. блокировка с файла не снимается,
 когда программа падает в корку.....
 
  Как можно вылечить?

OS - Solaris 9, gcc version 3.4.2
« Последнее редактирование: 20-12-2007 20:20 от Алексей1153++ » Записан
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 19-08-2005 15:38 » 

Такого быть не должно Жаль  Man соляриса утверждает, что

All locks associated with a file for a given process are removed when a file descriptor for that file is closed by that process or the process holding that file descriptor terminates.

(см. http://docs.sun.com/app/docs/doc/816-1056/6m7gi1i17?a=view)
Посмотри, может быть процесс висит как зомби?

Я точно не помню, но, по-моему, обработчики, установленные вызовом atexit вызываются даже в случае не маскируемых сигналов.  После того, как процесс захватил файл, установи средствами atexit функцию, которая закроет файловый дескриптор при завершении работы приложения.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 19-08-2005 15:41 » new

Время жизни таких вещей как блокировки файлов определяется временем жизни процесса - см. в памяти - может он не умер. Или что-то не так с реализацией блокировок в этой ОС.

Цитата
Код:
if ( (f = open(name, O_RDWR | O_CREAT)) > 0 )
Не "> 0" , а "!= -1"! Номера дескрипторов начинаются с нуля!

Цитата
Код:
mylock.l_type = F_WRLCK;
if ( (fc = fcntl(f, F_SETLK, &mylock)) != -1 )
F_SETLK и F_SETLKW блокируют области файла и struct flock содержит не одно поле - дело может быть в этом.

http://yumi.ziet.zhitomir.ua/ct/operating_systems/manpages/FCNTL.2.shtml
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines