Обработка сбоев mq_open после mq_unlink

Я пишу клиент-серверный процесс в Suse Linux, используя для связи очереди сообщений Posix, аналогично принятому ответу в разделе " Как использовать mqueue в программе ac в системе на основе Linux? ". Когда сервер умирает, он выполняет mq_close и mq_unlink. Однако клиент не получает уведомления об этом, поэтому вызовы mq_send в клиенте будут продолжать работать, даже если очередь не была связана.

Проблема в том, что когда сервер перезапускается, он пытается создать очередь с mq_open с помощью O_CREAT, но это не удается, потому что у клиента все еще есть открытый fd. Таким образом, даже если имя файла в / dev / mqueue, по-видимому, не существует, сервер не может создать его, пока клиент не завершит работу и не закроет свой файловый дескриптор. Я просто хотел убедиться, что правильно понимаю: если я хотел, чтобы сервер закрывал, отменял связь и снова открывал mqueue (например, с другими атрибутами), нужен ли ему клиент для выхода или закрытия своего fd? Это сильно отличается от способа работы с обычным файлом: я могу удалить файл, который использует другой процесс, и файловая система может переименовать его в ".nfsXXX", и они могут продолжать его использовать, но я могу сделать новый файл с этим именем сразу.

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

В идеале мне бы хотелось, чтобы новый mq_open успешно выполнялся на сервере, а следующий mq_send - на клиенте. Есть ли простой способ симулировать это? Пути, которые приходят мне в голову:

  • Выполнение fstat (или чего-то еще) в "/dev/mqueue/queueName" перед каждым mq_send (yuck!) И закрытие fd, если имя не существует (в то время как сервер пытается воссоздать его в цикле), но даже это не работает идеально, если клиент в настоящее время заблокирован на mq_send, потому что очередь была заполнена.
  • иметь отдельный сокет в клиенте, на который сервер будет отправлять сообщения, когда он хочет, чтобы клиенты закрыли свои mqueues (и, возможно, отдельный поток в клиенте для мониторинга этого сокета).
  • сделать так, чтобы сервер убил клиента.

0 ответов

Другие вопросы по тегам