Я долго искал портативное надежное решение для многопроцессорной синхронизации. Кто касается этих вещей, знает, что хорошее решение — это повышение :: iterprocess named
синхронизировать объекты. Но ….
Когда у вашего процесса named_mutex заблокирован и ваш процесс умирает (есть много нормальных ситуаций, когда процесс умирает, а не просто ошибка или другие.) В этом случае named_mutex останется в заблокированном состоянии. Была попытка сделать robust_mutex в буст-коде Ион Гастанага (Www.boost.org/doc/libs/1_55_0/boost/interprocess/detail/robust_emulation.hpp)
У него была хорошая идея, как решить отказ от государственной проверки. Каждый процесс в игре имеет свой собственный файл блокировки, и пока он жив, он удерживает этот файл заблокированным. Затем Ion robust_mutex проверяет, в случае неудачной попытки блокировки, текущий файл блокировки процесса владельца и может определить, активен ли текущий владелец мьютекса или нет. В случае смерти мьютекс может быть взят. Уловка с блокировкой файлов — хорошая идея, потому что блокировки файлов разблокируются ОС в случае, если процесс умирает, и это, кажется, хорошо переносимо. Это решение оборачивает базовый spin_mutex и хранит идентификатор текущего владельца во внутреннем поле. Я сделал интенсивное тестирование и обнаружил 2 большие проблемы.
Обработка блокировки файлов и способы ее реализации замедляют мьютекс таким образом, что это быстрее, просто используйте блокировку файлов.
Разъединение эффективной переменной шлюза и идентификатора процесса-владельца приводит к ситуациям, когда мьютекс может быть украден различными процессами.
И тут возникает мой вопрос: я предлагаю решение для обеих проблем, и мне нравится иметь профессиональное мнение по этому поводу.
не используйте для каждого существующего процесса отдельный файл блокировки, но используйте один файл для всех возможных идентификаторов процесса (должно быть достаточно 4 МБ) и для каждой блокировки процесса только один байт. Позиция этого байта определяется самим идентификатором процесса. (это не моя идея, но я нашел это в коде Говард Чу и его превосходный LMDB)
не оборачивайте spin_mutex как есть, но переписывайте его код, чтобы он использовал в качестве идентификатора текущего владельца шлюза шлюза вместо 0/1, чтобы блокировки и разблокировки могли происходить в одной атомарной операции CAS.
Я попытался реализовать это и протестировал на Windows. Я использую оригинальный код повышения и при необходимости называю повышение. Вот код. Он взят из дерева наших проектов, поэтому, если вы хотите протестировать его, вы можете адаптировать некоторые из них, возможно. Это предложение, поэтому, пожалуйста, не вините меня за стиль кода или что-то еще. Если идея и режим хороши, я продолжу делать их более совершенными. Если нет, я просто буду использовать что-то еще, но я не могу найти что-нибудь еще.
Также есть версии для recursive_mutex и named_mutex. Тогда есть своего рода
предложение по исправлению, потому что если один процесс захватывает владелец корабля, ранее отказавшийся от мьютекса, существует высокая вероятность того, что должна быть сделана какая-то проверка целостности.
Я хотел бы обсудить возможные улучшения
заранее спасибо
Ладислав.
Задача ещё не решена.