Как справиться с убийством (kill -9) при использовании общей памяти?

Я использую общую память в модели клиент-сервер. Когда мой сервер отключен пользователем с помощью sigkill вместо sigterm / sigint, я ничего не могу с этим поделать (как и предполагалось), но мой объект общей памяти и семафоры все еще существуют в / dev / shm /.

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

Пользователь должен будет удалить объекты самостоятельно - что, конечно, не самое лучшее.

Как мне с этим справиться?

Я мог бы просто вызвать shm_open () без флага O_EXCL, в конечном итоге разрушив назначение этого флага. Потому что, возможно, экземпляр моего сервера уже запущен и использует этот объект.

Pulseaudio, похоже, использует комбинацию цифр, чтобы объекты были различимы, и на него не влияет убийство с помощью -9, так что, похоже, есть способ.


person Haini    schedule 10.01.2016    source источник
comment
Разве у вас нет других способов идентифицировать уже запущенный серверный процесс? Может быть, файл pid?   -  person moooeeeep    schedule 10.01.2016
comment
@moooeeeep Вот почему я спрашиваю, как с этим бороться - кажется, хорошее начало, но где мне найти такой файл?   -  person Haini    schedule 10.01.2016


Ответы (2)


Схема возможной инициализации сервера:

Открыть файл pid с O_EXCL | O_WRONLY в случае успеха написать pid close Open shm w / O_CREAT done

открыть файл pid с O_RDONLY прочитать pid Используйте kill (0), чтобы проверить, жив ли сервер Если да, выйти Если нет, удалить файл pid Закройте pid, начните снова сверху

Pid-файлы обычно находятся в каталоге / var / run и называются foobar.pid, где foobar - это имя программы.

person John Hascall    schedule 10.01.2016
comment
Итак, в сочетании с этим unix .stackexchange.com / questions / 12815 / Я понимаю, к чему это ведет. Похоже на то, что нужно сделать. Спасибо! Приму этот ответ, если через несколько часов не появится ничего проще. - person Haini; 10.01.2016

Один из вариантов - использовать IPC_RMID (см. this).

Эта опция отмечает сегмент shm для очистки после того, как последний присоединенный к нему процесс исчезнет.

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

У вас также есть возможность использовать блокировки файлов, которые снимаются, если процесс завершается (см. lockf () < / а>).

person Ziffusion    schedule 10.01.2016
comment
Можно ли получить shmid при использовании функций из SHM_OVERVIEW (7), например способ с общей памятью POSIX? Я не вижу способа получить это, поскольку операции с общей памятью System V и операции с общей памятью POSIX, похоже, работают немного по-разному. По-прежнему отличный вклад, нелегко получить все возможности, которые у меня есть. - person Haini; 10.01.2016
comment
Не уверен, что это сработает для вашего варианта использования, но если вы можете вызвать shm_unlink() после того, как все процессы открыли shm по имени, это даст аналогичный эффект очистки shm после исчезновения процессов. - person Ziffusion; 10.01.2016
comment
К сожалению, я не могу вызвать shm_unlink (), когда получаю sigkill. Вызов его в любое время до этого был бы катастрофой, поскольку никакие новые клиенты не могли открыть SHM после его вызова. В противном случае это был бы хороший трюк. - person Haini; 10.01.2016
comment
Кажется, да, хотя очень грустно, что я не могу решить ее по-вашему. Отличный пример, спасибо! - person Haini; 10.01.2016
comment
Параметр IPC_RMID используется только для общей памяти System V? - person mpr; 22.05.2018