Предотвращение нескольких экземпляров процесса на Linux

Каков лучший способ на платформе Linux для процесса (приложение C++), чтобы проверить, что его экземпляр уже не работает?

5
задан skaffman 3 June 2010 в 08:50
поделиться

5 ответов

Стандартный способ сделать это - создать где-нибудь pid-файл, обычно содержащий pid вашей программы.

Вам не обязательно помещать туда pid, вы можете просто наложить на него эксклюзивную блокировку. Если вы откроете его для чтения/записи и заблокируете его с помощью LOCK_EX | LOCK_NB, это приведет к ошибке, если файл уже заблокирован. Это не приводит к возникновению условий гонки, и блокировка будет автоматически снята, если программа завершится аварийно.

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

Если это демон, то лучше в /var/run.

5
ответ дан 13 December 2019 в 22:02
поделиться

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

Вы можете использовать либо некоторые библиотеки ( libunique (GTK +) или QtSingleApplication (Qt)), либо сделать это самостоятельно. В дополнение к pid-файлу, упомянутому ранее, вы можете открыть сокет FIFO или UNIX-домена где-нибудь в домашнем каталоге пользователя. Таким образом, вы можете общаться с запущенным экземпляром, например. поднять окно запущенного экземпляра или указать запущенному экземпляру, чтобы он открывал новый файл / URI / что-то еще.

0
ответ дан 13 December 2019 в 22:02
поделиться

Для этого можно использовать файлы и блокировки файлов, но будьте осторожны, это не идеально, и не копируйте печально известную ошибку 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 (т.е. действовать как мьютекс, чтобы сделать его безопасным. с точки зрения параллелизма на уровне процессов).

5
ответ дан 13 December 2019 в 22:02
поделиться

Связанная альтернатива решению Майкла - создать каталог в известном месте (вероятно, в / var / run или / tmp) и использовать успех / неудачу системного вызова в качестве механизма для обеспечения взаимного исключения. Это тот же прием взаимного исключения, который CVS использовала в течение многих лет, поскольку создание каталогов атомарно в большинстве (а может и во всех) массовых операционных системах. Файл PID по-прежнему полезен в случае, когда процесс создания каталога + PID неожиданно завершает работу и не может быть очищен. Кроме того, при проверке допустимости существующего каталога + PID я бы предложил явно проверить символическую ссылку / proc / / exe , чтобы убедиться, что она указывает на ваш исполняемый файл, а не просто предполагать, что PID не был переработан.

1
ответ дан 13 December 2019 в 22:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: