Windows - Как очистить объект общей памяти, оставленный процессами, завершившимися аварийно?

Я столкнулся с проблемой, когда процесс завершился ненормально, и, следовательно, некоторые общие ресурсы (BaseNamedObjects) остались невысвобожденными процессом.

Функция CreateFileMapping возвращает ERROR_ALREADY_EXISTS, что указывает на то, что разделяемая память уже существует.

После получения ERROR_ALREADY_EXISTS с помощью CreateFileMapping возвращается дескриптор. Итак, у меня есть следующие запросы, связанные с вышеуказанным сценарием:

  1. Можем ли мы выполнить очистку, используя этот возвращенный дескриптор?
  2. Можем ли мы использовать дескриптор, возвращаемый CreateFileMapping?
  3. как очистить такой объект общей памяти?

person Priyanka Shinde    schedule 04.06.2018    source источник
comment
Ваш диагноз кажется неверным. Если бы все процессы, открывшие дескрипторы на этот объект, завершились, то система уже бы его очистила. Таким образом, все еще должен быть существующий процесс, который имеет дескриптор объекта.   -  person David Heffernan    schedule 04.06.2018
comment
если вы не создаете объект с OBJ_PERMANENT (для этого нужно использовать собственный API и иметь специальные привилегии - так что можете считать, что нет) - объект будет автоматически уничтожен, когда все дескрипторы для него закрыты (имя будет удалено) и ссылка освобождена (ссылка может быть из сопоставления разделов). не нужно делать специальную очистку. не все процессы, у которых есть этот дескриптор, завершены, если вы получили ERROR_ALREADY_EXISTS   -  person RbMm    schedule 04.06.2018
comment
Вы, вероятно, просто используете общее имя для вашего объекта сопоставления файлов, и кто-то еще делает то же самое. Но как мы должны знать, не видя минимально воспроизводимый пример?   -  person IInspectable    schedule 04.06.2018
comment
Вы дали имя области общей памяти? Если это так, вы сможете найти его (и посмотреть, какие приложения его используют) в Обозреватель процессов.   -  person Paul Sanders    schedule 04.06.2018


Ответы (1)


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

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

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

Возможно, другой ваш процесс на самом деле не умер, а находится в состоянии фатального зацикливания или безнадежного ожидания. Чтобы выйти из этого случая, вы можете сохранить все идентификаторы процессов в общей области, и любой новый процесс с доступом к общей области может УБИТЬ всех старых участников.

person Gem Taylor    schedule 04.06.2018