Каков наилучший способ на платформе Linux для процесса (приложение C++) проверить его экземпляр еще не запущен?Предотвращение нескольких экземпляров процессов в Linux
ответ
Стандартный способ сделать это - создать pidfile где-нибудь, обычно содержащий pid вашей программы.
Вам не нужно вставлять pid, вы можете просто установить на него эксклюзивный замок. Если вы откроете его для чтения/записи и скопируйте его с помощью LOCK_EX | LOCK_NB, он не будет работать, если файл уже заблокирован. Это состояние гонки бесплатно, и блокировка будет автоматически выпущена, если программа выйдет из строя.
Обычно вы хотите сделать это для каждого пользователя, поэтому домашний каталог пользователя является хорошим местом для размещения файла.
Если это демон, где-то вроде/var/run лучше.
Для этого вы можете использовать файлы и блокировки файлов, но будьте осторожны, это не идеально, и не копируйте печально известную ошибку Firefox, где она иногда отказывается запускать, даже если она еще не запущена.
Основная логика этого является:
Invariant:
File xxxxx will exist if and only if the program is running, and the
contents of the file will contain the PID of that program.
On startup:
If file xxxxx exists:
If there is a process with the PID contained in the file:
Assume there is some instance of the program, and exit
Else:
Assume that the program terminated abnormally, and
overwrite file xxxx with the PID of this program
Else:
Create file xxxx, and save the current PID to that file.
On termination (typically registered via atexit):
Delete file xxxxx
В дополнение к выше логики, вы должны также использовать второй файл, который вы блокировки для синхронизации доступа к файлу PID (т.е. выступать в качестве мьютекс, чтобы сделать его безопасным с точки зрения параллелизма на уровне процесса).
Связанная альтернатива решению Майкла состоит в том, чтобы создать каталог в известном месте (возможно, в/var/run или/tmp) и использовать успех/отказ системного вызова в качестве механизма обеспечения взаимного исключения. Это то же самое взаимное исключение, которое CVS использовал в течение многих лет, поскольку создание каталогов является атомарным для большинства (возможно, всех) товарных ОС. PID-файл по-прежнему полезен в случае, когда процесс создания каталога + PID неожиданно завершается и не удается выполнить очистку. Кроме того, при проверке, действительно ли существующий каталог + PID действителен, я предлагаю явно проверить символическую ссылку /proc/<PID>/exe
, чтобы убедиться, что она указывает на ваш исполняемый файл, а не просто на то, что PID не был повторно использован.
Чтобы сделать это, вы можете использовать POSIX named semaphore. Это гораздо безопаснее, чем использование блокировки файлов.
Как это касается программы, которая разбилась без очистки семафора? –
из справочной страницы: POSIX семафоры имеют стойкость ядра: если не удалить sem_unlink(), семафор будет существовать до тех пор, пока система не будет отключена. Проблема, безусловно, будет проблемой здесь. – jackhab
Для настольного приложения, вероятно, более вероятно проверить, запущен ли экземпляр для текущего пользователя, чтобы два пользователя могли запускать свои собственные экземпляры.
Вы можете использовать либо некоторые библиотеки (libunique (GTK +), либо QtSingleApplication (Qt)), либо сделать это самостоятельно. В дополнение к pid-файлу, упомянутому ранее, вы можете открыть сокет FIFO или UNIX-домен где-нибудь в домашнем каталоге пользователя. Таким образом, вы можете общаться с запущенным экземпляром, например. поднять окно исполняемого экземпляра или сообщить исполняемому экземпляру, чтобы открыть новый файл/URI/что угодно.
- 1. Предотвращение нескольких экземпляров объекта
- 2. Предотвращение нескольких экземпляров службы
- 3. Предотвращение нескольких экземпляров приложения GTK
- 4. Предотвращение запуска нескольких экземпляров jar
- 5. Предотвращение нескольких экземпляров процесса одного исполняемого файла
- 6. Предотвращение нескольких экземпляров страницы в TabControl
- 7. Предотвращение нескольких экземпляров в активности веб-просмотра
- 8. Предотвращение отображения нескольких экземпляров одной формы из
- 9. Предотвращение нескольких экземпляров службы - лучший подход?
- 10. Предотвращение прерывания с запуском нескольких экземпляров
- 11. Предотвращение открытия нескольких экземпляров приложения VB
- 12. Предотвращение множественных экземпляров формы
- 13. Запуск нескольких экземпляров megasync в Linux
- 14. Предотвращение процессов зомби в самоинсталлированной оболочке Linux (C++)
- 15. Выполнение нескольких процессов C++-программы
- 16. Несколько процессов в linux
- 17. Предотвращение новых экземпляров модели
- 18. Предотвращение дублирования экземпляров в window.history
- 19. Предотвращение множественных экземпляров Java-фрейма
- 20. Предотвращение нескольких экземпляров одноэлементного объекта с помощью плагинов excel
- 21. Планировщик процессов Linux
- 22. Максимальное количество процессов в Linux
- 23. Переключение процессов ядра в Linux
- 24. Проверка убитых процессов в Linux
- 25. блокировка перекрестных процессов в linux
- 26. Создание дочерних процессов в Linux
- 27. Отладка нескольких разветвленных процессов в * nix
- 28. Предотвращение несколько экземпляров моего приложения
- 29. Запуск нескольких экземпляров ffmpeg
- 30. Несколько потоков против нескольких процессов
Не проще ли использовать сокет вместо файла и попытаться связать его с предопределенным портом? И, кстати, почему я не могу использовать блокировку файлов без проверки pid? – jackhab
@ Jack, вы можете сделать это без проверки PID, но тогда вы рискуете предположить, что программа открыта, когда она действительно разбилась и не удалось очистить файл (подумайте о проблеме с Firefox). Кроме того, Rakis поднимает хороший момент, то есть в Linux вы можете проверить, принадлежит ли PID вашей программе, используя данные в '/ proc' ... существуют программные способы сделать это более общее в вариантах UNIX (по крайней мере, вы могли бы вызывать «ps» и анализировать его вывод, хотя я считаю, что могут быть функции, которые вы можете вызвать для получения информации о процессе напрямую). –
, чтобы проверить существование процесса, вызвать kill (pid, 0). Это происходит успешно, когда процесс существует, и в противном случае не выполняется. Остерегайтесь процесса, запущенного на другой машине! – Arkadiy