2016-02-25 3 views
1

Впервые работая с сокетами домена Unix, теперь я пытаюсь реализовать часть очистки.Unlink/cleanup unix socket, только если он по-прежнему принадлежит процессу

Было уже немного уродливо, что общая рекомендация при создании вашего слухового сокета заключается в том, чтобы сначала отключить нужный путь сокета, а затем вызвать bind. Хотя вы, вероятно, должны убедиться, что ваш процесс работает только один раз, я пытаюсь подготовиться к ситуации, когда по какой-то причине он будет запущен дважды. Для самой службы это не имеет большого значения: сокет первого экземпляра отсоединяется вторым экземпляром, поэтому он недоступен, отнимает некоторую ОЗУ, но не наносит никакого вреда. Но как я могу реализовать очистку, которая работает в этой ситуации? Просто делать

close(sockFd); 
unlink(sockPath); 

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

Я могу только подумать о нескольких уродливых хаках, которые не были бы атомарными, поэтому все равно могут испортиться, поэтому я надеюсь, что есть лучшая парадигма, чтобы не допустить этого. Что-то вроде funlink (sockFd) было бы хорошо. В противном случае мне пришлось бы прибегнуть к тому, чтобы никогда не очищать сокет, что еще не конец света, но мне кажется, что он довольно запутан.

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

+0

Вот что я обычно делаю, чтобы избежать двух процессов, пытающихся прослушивать один и тот же доменный домен unix. Первое, что я делаю, это попытаться подключиться к сокету. Если соединение работает, уже работает прослушиватель, я выручаю. В противном случае я разрешу продолжить процесс и прослушивать сокет. Очистка должна быть простой, потому что вы уверены, что у вас всего 1 слушатель. – alvits

+0

Правильный подход заключается в попытке привязки к сокету, и вы получите 'EADDRINUSE', если сокет уже используется. Теперь вы знаете, что другой процесс уже прослушивает его, вы можете выручить. – alvits

+0

@alvits Я думаю, что вы получаете EADDRINUSE, даже если первый процесс вышел, и осталось только затянутый сокет в файловой системе, так что это не лучше, чем немедленное удаление сокета при запуске, но подключение до привязки может быть опцией; Я попробую немного ... – Simon

ответ

0

Вы можете использовать отдельный файл блокировки, который ваше приложение блокирует с помощью flock(..., LOCK_EX), прежде чем что-либо делать с сокетом. Пока все экземпляры приложений согласуются с тем, какой файл блокировки использовать, вы в безопасности, а flock() является атомарным. Очистка не является проблемой с flock(), поскольку блокировка высвобождается, когда процесс умирает.

 Смежные вопросы

  • Нет связанных вопросов^_^