Уведомления

Группа в Telegram: @pythonsu

#1 Март 8, 2014 06:24:23

Alen
Зарегистрирован: 2013-08-01
Сообщения: 373
Репутация: +  49  -
Профиль   Отправить e-mail  

Кроссплатформенная блокировка повторного запуска.

fedorch
Но в случае перезагрузки системы вероятность коллизий многократно возрастает.

В случае перезагрузки компьютера вероятность колизии равна 0. По завершению программы файл удаляется.

fedorch
Но на нем не бежит ни чего, что активно генерировало новые процессы.

CRON же, плюс возможно Apache в режиме prefork.

fedorch
Соглашусь, что в нормальном режиме работы вероятность коллизий невелика, хотя о годах речь не идет ;-)

Я ничего не изобретал, это стандартная блокировка в Unix уже как 40-50 лет. Ничего лучше не придумали. Если вам очень хочется полностью избавится от коллизий проверяйте не просто pid, а и имя процесса.

Офлайн

#2 Март 8, 2014 06:56:56

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Кроссплатформенная блокировка повторного запуска.

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



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#3 Март 8, 2014 07:01:20

Alen
Зарегистрирован: 2013-08-01
Сообщения: 373
Репутация: +  49  -
Профиль   Отправить e-mail  

Кроссплатформенная блокировка повторного запуска.

Можете вообще обойтись без файла блокировки

import sys
import platform
import subprocess
system = platform.uname()[0]
if system in ('Darwin', 'Linux', 'FreeBSD'):
    p = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE)
elif system in 'Windows':
    p = subprocess.Popen(['tasklist'], stdout=subprocess.PIPE)
else:
    sys.stderr.write('unknown OS')
    sys.exit()
out, _ = p.communicate()
if out.count(sys.argv[0]) >= 2:
    sys.stderr.write('program is already running')
    sys.exit()
   

Отредактировано Alen (Март 8, 2014 07:52:08)

Офлайн

#4 Март 8, 2014 07:08:12

fedorch
От: Москва (чаще всего)
Зарегистрирован: 2014-03-07
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

Кроссплатформенная блокировка повторного запуска.

Благодарю всех откликнувшихся. Буду пробовать.

Офлайн

#5 Март 8, 2014 16:26:55

lorien
От:
Зарегистрирован: 2006-08-20
Сообщения: 755
Репутация: +  37  -
Профиль  

Кроссплатформенная блокировка повторного запуска.

Я такую штуку пользую: https://github.com/lorien/grab/blob/master/grab/tools/lock.py#L58

Суть в том, что открываем файл и лочим его. Проблемы с крахом программы или перезагрузкой ОС - нету. Лок снимется автоматически.

Отредактировано lorien (Март 8, 2014 16:28:33)

Офлайн

#6 Март 8, 2014 18:59:10

fedorch
От: Москва (чаще всего)
Зарегистрирован: 2014-03-07
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

Кроссплатформенная блокировка повторного запуска.

lorien
Суть в том, что открываем файл и лочим его. Проблемы с крахом программы или перезагрузкой ОС - нету. Лок снимется автоматически.
Ну так я и пытался сделать что-то подобное, только гораздо проще. И это у меня на половину ;-) получилось.

Под Виндой (проверил на XP, 7 и 2003 Server) всё отлично работает - ни какие блокировки файла вообще не нужны.

А вот с Linux - засада. Там, как сейчас оказалось, можно запросто стереть файл в который кто-то сейчас пишет и этот кто-то даже ничего и не заметит и будет продолжать писать в несуществующий больше файл и дальше. И ни кто на это внимания не обратил.

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

Офлайн

#7 Март 8, 2014 19:07:06

lorien
От:
Зарегистрирован: 2006-08-20
Сообщения: 755
Репутация: +  37  -
Профиль  

Кроссплатформенная блокировка повторного запуска.

Под виндой ваш код, по крайней мере тот, что в начале топика, тоже может глючит. Например, процесс проверил, что файла блокировки нет и начал его создавать. Но между тем как он проверил и тем, как он начал создавать файл, другой процесс уже успел создать файл. У вас будут запущены два процесса и оба будут думать, что они работают в единственном экземпляре.

Офлайн

#8 Март 8, 2014 19:31:32

Alen
Зарегистрирован: 2013-08-01
Сообщения: 373
Репутация: +  49  -
Профиль   Отправить e-mail  

Кроссплатформенная блокировка повторного запуска.

fedorch
А вот с Linux - засада. Там, как сейчас оказалось, можно запросто стереть файл в который кто-то сейчас пишет и этот кто-то даже ничего и не заметит и будет продолжать писать в несуществующий больше файл и дальше. И ни кто на это внимания не обратил.

Вообще то в первом же ответе.

Alen
В Linux/MacOS X/BSD работать не будет

Офлайн

#9 Март 8, 2014 19:52:11

fedorch
От: Москва (чаще всего)
Зарегистрирован: 2014-03-07
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

Кроссплатформенная блокировка повторного запуска.

lorien
Под виндой ваш код, по крайней мере тот, что в начале топика, тоже может глючит. Например, процесс проверил, что файла блокировки нет и начал его создавать. Но между тем как он проверил и тем, как он начал создавать файл, другой процесс уже успел создать файл. У вас будут запущены два процесса и оба будут думать, что они работают в единственном экземпляре.
Спасибо, первая конструктивная критика моего кода, а не предложение сделать (по другому, как у всех, как принято 50 лет).

lorien
Я такую штуку пользую: https://github.com/lorien/grab/blob/master/grab/tools/lock.py#L58
При внимательном изучении этого кода обнаружил одну странность. Если в Unix части перехватываются вообще ВСЕ исключения от flock(), что не хорошо, но частично оправданно, так как в разных версиях там генерируются разные типы исключений. То в Windows части перехватывается только одно исключение от LockFileEx() и у него проверяется код ошибки. Получается, что если блокировка не получилась по причине наличия другой блокировки, то возвращаем False и считаем, что блокировка не удалась. А, если блокировка не получилась по какой то другой причине, то возвращаем True и считаем, что блокировка удалась ;-(

Alen
Вообще то в первом же ответе.
Alen
В Linux/MacOS X/BSD работать не будет

Извините, не понимаю, как я пропустил эту фразу…

Офлайн

#10 Март 8, 2014 23:18:21

lorien
От:
Зарегистрирован: 2006-08-20
Сообщения: 755
Репутация: +  37  -
Профиль  

Кроссплатформенная блокировка повторного запуска.

То в Windows части перехватывается только одно исключение от LockFileEx() и у него проверяется код ошибки. Получается, что если блокировка не получилась по причине наличия другой блокировки, то возвращаем False и считаем, что блокировка не удалась. А, если блокировка не получилась по какой то другой причине, то возвращаем True и считаем, что блокировка удалась ;-(
Да фиг знает, мне если честно, по барабану как этот код работает под виндой т.к. я использую его исключительно под linux. Если кто-то найдёт там баг в windows-реализации и пришлёт патч, конечно, я буду рад применить его к исходному коду :)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version