На StackOverflow есть отличный ответ о предоставлении лучшей блокировки для демонов (синтезированных из Eduardo Fleury ), которая не зависит от общего механизма блокировки файлов PID для демонов. Там есть много хороших комментариев о том, почему файлы блокировки PID могут иногда вызывать проблемы, поэтому я не буду перефразировать их здесь.
Короче говоря, решение опирается на абстрактные доменные сокеты Linux, которые отслеживают сокеты по имени, а не на файлах, которые могут остаться после того, как демон SIGKILL'd. Пример показывает, что Linux, кажется, освобождает сокет, когда процесс мертв.
Но я не могу найти в Linux исчерпывающую документацию, в которой говорится, что именно Linux делает с абстрактным сокетом, когда связанный процесс выполняется SIGKILL. Кто-нибудь знает?
Иными словами, когда точно освободится абстрактный сокет для повторного использования?
Я не хочу заменять механизм файлов PID на абстрактные сокеты, если это не решит проблему окончательно.
источник
Ответы:
Да, linux автоматически «очищает» абстрактные сокеты до такой степени, что очистка даже имеет смысл. Вот минимальный рабочий пример, с помощью которого вы можете проверить это:
Запустите эту программу как
./a.out /test-socket &
, затем запуститеss -ax | grep test-socket
, и вы увидите, что сокет используется. Тогдаkill %./a.out
иss -ax
покажет сокет ушел.Однако причина, по которой вы не можете найти эту очистку в какой-либо документации, заключается в том, что она на самом деле не очищает в том же смысле, что неабстрактные сокеты домена unix требуют очистки. Неабстрактный сокет фактически выделяет индекс и создает запись в каталоге, которую необходимо очистить в базовой файловой системе. Напротив, думайте об абстрактном сокете больше как номер порта TCP или UDP. Конечно, если вы связываете порт TCP и затем выходите, этот порт TCP снова будет свободен. Но какой бы 16-битный номер вы ни использовали, он существует абстрактно и всегда существует. Пространство имен номеров портов - 1-65535 и никогда не изменяется и не нуждается в очистке.
Так что просто подумайте об абстрактном имени сокета, как о номере порта TCP или UDP, просто выберите из гораздо большего набора возможных номеров портов, которые выглядят как пути, но не являются таковыми. Вы не можете связать один и тот же номер порта дважды (за исключением
SO_REUSEADDR
илиSO_REUSEPORT
). Но закрытие сокета (явным или неявным путем завершения) освобождает порт, и нечего очищать.источник
Я разместил этот вопрос более года назад и никогда не был полностью удовлетворен отсутствием окончательной документации. Я подумал, что еще раз проверю документацию Linux на наличие обновлений, и был счастлив увидеть это :
Кроме того , в Linux Программирование интерфейса по Майклу Керриск охватывает вопрос (кросс отправленный от этого другого ответа ):
Я считаю, что вместе с ответом @ user3188445 это очень точно проясняет вопрос.
Тем не менее, здесь все еще делается предположение, что для процессов, которые являются SIGKILL, все открытые сокеты будут закрыты. Это кажется разумным предположением, но у меня нет документации, определяющей это поведение.
источник
SOCK_CLOEXEC
если какой-либо код (включая библиотеку) когда-либо выполняет fork () + exec (). Создание дополнительных дочерних процессов с использованием fork () без exec () встречается реже; Вы, наверное, уже знаете, делаете ли вы это.