Как реализовать проверку - запущено приложение или нет?
От: lexius www.acula.org
Дата: 01.11.06 17:52
Оценка:
Нужно запретить запуск нескольких копий одного и того же приложения, подскажите как это сделать. Есть мысль через сокеты сделать....
************
www.acula.org
Re: Как реализовать проверку - запущено приложение или нет?
От: Blazkowicz Россия  
Дата: 01.11.06 17:55
Оценка:
Здравствуйте, lexius, Вы писали:

L>Нужно запретить запуск нескольких копий одного и того же приложения, подскажите как это сделать. Есть мысль через сокеты сделать....


Поддерживаю
Автор: Blazkowicz
Дата: 25.09.06
http://rsdn.org/File/13923/ukliam3.gif
Re: Как реализовать проверку - запущено приложение или нет?
От: Gurney Великобритания www.kharlamov.biz
Дата: 01.11.06 18:11
Оценка:
lexius wrote:

> Нужно запретить запуск нескольких копий одного и того же приложения,

> подскажите как это сделать. Есть мысль через сокеты сделать....

Можно также создавать файл во временной директории, и держать его
открытым пока работает приложение. При запуске проверять наличие этого
файла, если есть — пытаться удалить. Если не получилось — работает
другой инстанс.

По сравнению с сокетами:
+ Вероятность ложного срабатывания меньше.
— Послать сообщение работающему приложению нельзя.

В конечном итоге мы использовали и сокеты, и файлы.
Posted via RSDN NNTP Server 2.0
Re[2]: Как реализовать проверку - запущено приложение или не
От: Alexandro Россия  
Дата: 02.11.06 00:13
Оценка:
Здравствуйте, Gurney, Вы писали:

G>lexius wrote:


>> Нужно запретить запуск нескольких копий одного и того же приложения,

>> подскажите как это сделать. Есть мысль через сокеты сделать....

G>Можно также создавать файл во временной директории, и держать его

G>открытым пока работает приложение. При запуске проверять наличие этого
G>файла, если есть — пытаться удалить. Если не получилось — работает
G>другой инстанс.
под unix-подобными не сработает.

G>По сравнению с сокетами:

G>+ Вероятность ложного срабатывания меньше.
G>- Послать сообщение работающему приложению нельзя.

G>В конечном итоге мы использовали и сокеты, и файлы.
С уважением,
Александр.
icq: 118852038
Re[2]: Как реализовать проверку - запущено приложение или не
От: Alexandro Россия  
Дата: 02.11.06 00:14
Оценка:
Здравствуйте, Gurney, Вы писали:

G>lexius wrote:


>> Нужно запретить запуск нескольких копий одного и того же приложения,

>> подскажите как это сделать. Есть мысль через сокеты сделать....

G>Можно также создавать файл во временной директории, и держать его

G>открытым пока работает приложение. При запуске проверять наличие этого
G>файла, если есть — пытаться удалить. Если не получилось — работает
G>другой инстанс.
под unix-подобными системами сработает?

G>По сравнению с сокетами:

G>+ Вероятность ложного срабатывания меньше.
G>- Послать сообщение работающему приложению нельзя.

G>В конечном итоге мы использовали и сокеты, и файлы.
С уважением,
Александр.
icq: 118852038
Re[3]: Как реализовать проверку - запущено приложение или не
От: Igor.K США  
Дата: 02.11.06 06:50
Оценка:
A>под unix-подобными не сработает.
Почему?
... << RSDN@Home 1.2.0 alpha rev. 653>>
"СССР — четыре слова и все лживые" — Вагрич Бахчанян
Re[4]: Как реализовать проверку - запущено приложение или не
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 02.11.06 08:32
Оценка:
Здравствуйте, Igor.K, Вы писали:

A>>под unix-подобными не сработает.

IK>Почему?
Так задумано
Автор: Andrei N.Sobchuck
Дата: 17.01.06
.
http://www.smalltalk.ru | << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[5]: Как реализовать проверку - запущено приложение или не
От: dualsoul  
Дата: 02.11.06 08:40
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>Здравствуйте, Igor.K, Вы писали:


A>>>под unix-подобными не сработает.

IK>>Почему?
ANS>Так задумано
Автор: Andrei N.Sobchuck
Дата: 17.01.06
.


Если Java 1.4 + можно такой сценарий:
1) Получаем FileLock
Если получилось — значит работает.
Нет — значит кто-то получил блокировку до нас.

Файлики удалять не надо, можно лочить например существующий в дистрибутиве.

Под RHEL работает. Правда не для проверки двойного запуска делали, но я думаю вполне подойдет.
Re[2]: Как реализовать проверку - запущено приложение или не
От: Blazkowicz Россия  
Дата: 02.11.06 10:06
Оценка:
Здравствуйте, Gurney, Вы писали:

G>По сравнению с сокетами:

G>+ Вероятность ложного срабатывания меньше.

Можно про вероятность ложного срабатывания поподробнее? Это откуда она? Если порт занят уже кем-то другим? Так это через обмен сообщениями и решается.
http://rsdn.org/File/13923/ukliam3.gif
Re[3]: Как реализовать проверку - запущено приложение или не
От: Gurney Великобритания www.kharlamov.biz
Дата: 02.11.06 14:31
Оценка:
Alexandro wrote:

> G>Можно также создавать файл во временной директории, и держать его

> G>открытым пока работает приложение. При запуске проверять наличие этого
> G>файла, если есть — пытаться удалить. Если не получилось — работает
> G>другой инстанс.
> под unix-подобными системами сработает?
Описанный алгоритм — нет. На *nix-ах действительно вместо попытки удаления
нужно пытаться захватить блокировку через FileLock.
Posted via RSDN NNTP Server 2.0
Re[3]: Как реализовать проверку - запущено приложение или не
От: Gurney Великобритания www.kharlamov.biz
Дата: 02.11.06 15:02
Оценка: 6 (1)
Blazkowicz wrote:
> Можно про вероятность ложного срабатывания поподробнее? Это откуда она?
> Если порт занят уже кем-то другим? Так это через обмен сообщениями и
> решается.
Допустим у вас на компьютере стоит некое приложение которое агрессивно
использует порты. Это могу быть IM-ры, P2P, традиционные сервера и т.д.
Если программа проверяет наличие другого инстанса по наличию открытого
порта, а этот порт уже занят др. процессом, то имеем ложное срабатывание
механизма ограничения повторного запуска. Конечно, это можно обойти
попыткой обмена сообщениями, но:
1. Если мы определили, что порт открыт, но не нашим приложением, что
делать дальше? Попытаться открыт другой порт? Но тогда нужно как-то
сообщить всем, что искать нужно на др. порту. Если через файл свойтсв,
то мы опять вернулись к связке файл с блокировкой/сокет.
2. Есть один довольно неприятный баг MS Firewall Client (в 2006-м, его
поправили), в результате которого Java приложения не могут открывать
серверные сокеты на 0.0.0.0. В результате, вполне может оказаться, что
ваше приложение не отвечает на условленному порту просто из-за того, что
оно просто не смогло открыть сокет. Сюда можно добавить возможные
проблемы с др. personal файрволами.
Posted via RSDN NNTP Server 2.0
Re[4]: Как реализовать проверку - запущено приложение или не
От: Blazkowicz Россия  
Дата: 02.11.06 15:13
Оценка:
Здравствуйте, Gurney, Вы писали:

G>1. Если мы определили, что порт открыт, но не нашим приложением, что

G>делать дальше? Попытаться открыт другой порт? Но тогда нужно как-то
G>сообщить всем, что искать нужно на др. порту. Если через файл свойтсв,
G>то мы опять вернулись к связке файл с блокировкой/сокет.
Зачем сообщать? Просто надо итерироватся дальше по номеру порта (или забить список предефайненых возможных портов)
На каждой итерации:
Если порт свободен — запускатся
Если порт занят — попытатся связатся с предыдущим экземпляром себя
Если ответили — закрываемся с чистой совестью
Если не ответили — повотряем итерацию для следующего порта.

В этой схеме есть ошибки?


G>2. Есть один довольно неприятный баг MS Firewall Client (в 2006-м, его

G>поправили), в результате которого Java приложения не могут открывать
G>серверные сокеты на 0.0.0.0. В результате, вполне может оказаться, что
G>ваше приложение не отвечает на условленному порту просто из-за того, что
G>оно просто не смогло открыть сокет. Сюда можно добавить возможные
G>проблемы с др. personal файрволами.

Да, про firewall не подумал. Спасибо.
http://rsdn.org/File/13923/ukliam3.gif
Re[3]: Как реализовать проверку - запущено приложение или не
От: relgames  
Дата: 02.11.06 15:18
Оценка:
Blazkowicz пишет:

> Можно про вероятность ложного срабатывания поподробнее? Это откуда она?

> Если порт занят уже кем-то другим? Так это через обмен сообщениями и
> решается.

Могу предположить ситуацию с работающим файерволом — может быть
запрещено порт открыть или отправить сообщение.
Posted via RSDN NNTP Server 2.0
Punk Not Dead
Re[5]: Как реализовать проверку - запущено приложение или не
От: Gurney Великобритания www.kharlamov.biz
Дата: 02.11.06 16:21
Оценка:
Blazkowicz wrote:

> Если порт свободен — запускатся

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

Очевидных проблем нет. Однако что-то мне в таком методе стрельбы
по квадратам не нравится. Хотя конечно случай сильно вырожденный
и вероятность наведенного сбоя достаточно низкая.

> Да, про firewall не подумал. Спасибо.

Плс.
Posted via RSDN NNTP Server 2.0
Re[5]: Как реализовать проверку - запущено приложение или не
От: xBlackCat Россия  
Дата: 02.11.06 16:55
Оценка: 16 (2)
Здравствуйте, Blazkowicz, Вы писали:

B>Здравствуйте, Gurney, Вы писали:


G>>1. Если мы определили, что порт открыт, но не нашим приложением, что

G>>делать дальше? Попытаться открыт другой порт? Но тогда нужно как-то
G>>сообщить всем, что искать нужно на др. порту. Если через файл свойтсв,
G>>то мы опять вернулись к связке файл с блокировкой/сокет.
B>Зачем сообщать? Просто надо итерироватся дальше по номеру порта (или забить список предефайненых возможных портов)
B>На каждой итерации:
B>Если порт свободен — запускатся
B>Если порт занят — попытатся связатся с предыдущим экземпляром себя
B>Если ответили — закрываемся с чистой совестью
B>Если не ответили — повотряем итерацию для следующего порта.

B>В этой схеме есть ошибки?


Ну можно предположить такой вариант развития событий для выделеной выше части:
Для приложения есть порт 100 и посделующие определяются итерированием.

Пусть p2p использует для закачки 100. Порт 101 свободен.
1. Приложение запускается. Порт 100 занят не нами — вешаемся на 101.
2. Закачка p2p завершается — порт 100 освобождается.
3. Второе приложение запускается. Порт 100 свободен и получаем второй инстанс.

IMHO, выход — ограниченный набор портов, которые будут сканироваться для проверки приложения на выполнение.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Rojac &mdash; Rsdn Offline JAva Client
Анонсы и обсуждение здесь
Автор: xBlackCat
Дата: 08.02.10
Re: Как реализовать проверку - запущено приложение или нет?
От: _Oleg_ Украина  
Дата: 03.11.06 07:48
Оценка:
Здравствуйте, lexius, Вы писали:

L>Нужно запретить запуск нескольких копий одного и того же приложения, подскажите как это сделать. Есть мысль через сокеты сделать....


Может через еще один компьютер-сервер, который будет регистрировать запущенные приложения.
При запуске приложение отправляет запрос серверу, на которое сервер отвечает ответом о возможности запуска.
Re[6]: Как реализовать проверку - запущено приложение или не
От: Cider Россия  
Дата: 03.11.06 09:06
Оценка: 6 (1) +1 -1
Здравствуйте, xBlackCat, Вы писали:

BC>IMHO, выход — ограниченный набор портов, которые будут сканироваться для проверки приложения на выполнение.


Чего-то я не понимаю, а почему бы просто не записывать захваченный порт в файл настроек? Второй инстанс прочитает файл и проверит этот порт, если он свободен — значит можно запускаться.
Cider
Re[5]: Как реализовать проверку - запущено приложение или не
От: kan Великобритания  
Дата: 03.11.06 09:07
Оценка: 7 (2) +1
Blazkowicz wrote:

> Да, про firewall не подумал. Спасибо.

Ещё подумай про многопользовательские ОС. Если на серваке (почти любой unix или Win TS) сидят два юзера и один из них
запустил аппликуху, другой уже не сможет, т.к. порты вещь глобальная на хост... уж лучше файлы в профиле юзера.
Если файловая система не поддерживает лочку, то в файл можно сохранить PID и проверять наличие процесса с данным PID.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[2]: Как реализовать проверку - запущено приложение или не
От: mselez  
Дата: 03.11.06 13:54
Оценка:
Здравствуйте, _Oleg_, Вы писали:

_O_>Здравствуйте, lexius, Вы писали:


_O_>Может через еще один компьютер-сервер, который будет регистрировать запущенные приложения.

_O_>При запуске приложение отправляет запрос серверу, на которое сервер отвечает ответом о возможности запуска.

И делать это надо по http, чтобы не было проблем с файерволами.
Re[7]: Как реализовать проверку - запущено приложение или не
От: C0s Россия  
Дата: 03.11.06 15:47
Оценка:
Здравствуйте, Cider, Вы писали:

C>Чего-то я не понимаю, а почему бы просто не записывать захваченный порт в файл настроек? Второй инстанс прочитает файл и проверит этот порт, если он свободен — значит можно запускаться.


захват порта и запись в файл не удастся реализовать атомарной операцией
Re: Как реализовать проверку - запущено приложение или нет?
От: lexius www.acula.org
Дата: 08.11.06 01:10
Оценка:
Я таки реализовал через сокеты и после нескольких дней тестирования сделал неутешительный вывод — работает не всегда. Я так и не понял от чего оно зависит, но иногда второй экземпляр таки можно запустить. Пробовал на разных портах и т.п. — все равно иногда запускается вторая копия.

Сделал через lock файла. теперь тестирую.

private File getAppFile() {
        return new File(AnuranUtils.getAnuranHomePath(), "anuran.lock");
    }

    private void lockInstance() throws IOException {
        File appFile = getAppFile();
        if (!appFile.exists()) {
            appFile.createNewFile();
        }
        RandomAccessFile userAppFile = new RandomAccessFile(appFile, "rw");
        FileChannel channel = userAppFile.getChannel();
        FileLock lock = channel.tryLock();
        if (lock == null) throw new IOException();
        appFile.deleteOnExit();
    }


Перед выходом файлик удаляю, дабы не мусолить им глаза (хотя...), но если выход будет некорректным — ничего страшного не случится.

Но мне все же интересно, чего при реализации через ServerSocket не работало?
Я использую jdk6, но не думаю, что дело в ней, как никак beta2 уже.
Метод не работал как под linux так и под windows. Может кто в курсе?
************
www.acula.org
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.