Я использую pthread_mutex_t
с PTHREAD_PROCESS_SHARED
на общей памяти, чтобы сделать синхронизацию между различными процессами.
Мьютекс может быть заблокирован, если процесс завершается, но оставляет мьютекс заблокированным. Eсть PTHREAD_MUTEX_ROBUST
в стандарте POSIX. Но похоже, что Mac OS X не поддерживает PTHREAD_MUTEX_ROBUST
,
Есть ли какая-то mutex
в Mac OS X, который можно использовать в общей памяти, чтобы использовать для синхронизации кросс-процессов и быть устойчивым в случае, если процесс умирает без его разблокировки?
Надежный материал появился в более поздней итерации потоков POSIX (SUSv7), не являющейся частью стандарта, поддерживаемого Mac OS X (то есть SUSv2).
Документы Apple не показывают pthread_mutexattr_setrobust
функция (или ее эквивалент get
) и они заявляют, что они основаны на SUSv2, поэтому это объясняет, почему у вас его нет.
С точки зрения фиксация проблема, вы можете рассмотреть что-то вроде использования atexit
обработчик для освобождения любых ресурсов, которыми может обладать ваша выходящая программа.
Или другой возможностью является внешнее наблюдение за тупиком и устранение неполадок. Например, у вас есть сторожевой процесс с двумя потоками по следующим строкам.
thread1:
set variables gloabalNum and localNum to zero
start thread2
while true:
sleep 60 seconds
if globalNum == localNum:
exit while
end if
localNum = globalNum
end while
kill all processes using mutex
remove shared memory
exit process
thread2:
while true:
lock mutex
unlock mutex
increment globalNum
sleep 5 second
Сторожевой таймер эффективно блокирует и разблокирует мьютекс каждые пять секунд, каждый раз увеличивая переменную. Если по какой-то причине вы зашли в тупик, thread2
остановится и переменная никогда не будет обновлена.
В это время, thread1
проверяет, чтобы убедиться, thread2
все еще работает, проверяя переменную по локальной копии каждую минуту. Если он находит, что они одинаковы, он предполагает thread2
остановлен из-за взаимоблокировки, а затем очищает все, закрывая все процессы, используя мьютекс, и уничтожая его (удаляя общую память).
Затем сторожевой таймер может завершить работу и, по-видимому, какой-либо код, который у вас уже есть для запуска всего приложения, в какой-то момент будет активирован. Или вы можете сделать так, чтобы сторожевой процесс вызывал какое-то предупреждение перед выходом, чтобы убедиться, что проблема обнаружена.
Идея сторожевого процесса состоит в том, чтобы сделать его как можно более простым, надеемся, до такой степени, что он будет правдоподобно правильным (или, по крайней мере, в большей степени, чем ваша ошибочная программа).
Без сомнения, есть много других возможностей в зависимости от вашей общей архитектуры. Я только что предоставил эти немногие из головы, чтобы вы могли подумать.