Как эмулировать shm_open в Windows? - PullRequest
3 голосов
/ 10 июля 2009

Моему сервису нужно хранить несколько бит информации (как минимум, не менее 20 бит или около того, но я легко могу использовать больше), так что

  • сохраняется при перезапусках службы, даже если служба аварийно завершилась или была прервана ненормально
  • не сохраняется после перезагрузки
  • может быть прочитано и обновлено с минимальными издержками

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

Теперь, если бы я работал в современной системе POSIX, я бы использовал shm_open, что позволило бы создать сегмент разделяемой памяти, который сохраняется при перезапуске процесса, но не при перезагрузке системы, и я мог бы использовать shm_unlink для очистки, если постоянные данные каким-то образом повреждены.

Я нашел MSDN: Создание именованной общей памяти и начал переопределять ее части в моем сервисе; это в основном использует CreateFileMapping(INVALID_HANDLE_NAME, ..., PAGE_READWRITE, ..., "Global\\my_service") вместо shm_open("/my_service", O_RDWR, O_CREAT).

Однако у меня есть несколько проблем, особенно связанных с временем жизни этого отображения на основе файла подкачки. Я не нашел ответы на эти вопросы в документации MSDN:

  • Сохраняется ли сопоставление при перезагрузках?
  • Если нет, то исчезает ли отображение, когда все открытые дескрипторы к нему закрыты?
  • Если нет, есть ли способ удалить или очистить сопоставление? Не должен быть во время использования.

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

Можете ли вы проверить или найти неисправности в этих точках и / или рекомендовать другой подход?


Если бы существовал каталог, который гарантированно был очищен при перезагрузке, я мог бы сохранить данные во временном файле, но он все равно не был бы идеальным: при определенных загрузках системы мы сталкиваемся с ошибками открытия / записи файла (редко, менее 0,01% времени, но все еще происходит), и эта функция должна использоваться в пути ведения журнала. Я бы не хотел больше вводить здесь файловые операции.

Ответы [ 2 ]

1 голос
/ 10 июля 2009

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

Попробуйте создать раздел реестра с RegCreateKeyEx с REG_OPTION_VOLATILE - данные не будут сохранены при выгрузке соответствующего куста. Это будет при отключении системы для HKLM или при выходе пользователя из системы для HKCU.

0 голосов
/ 10 июля 2009

звучит так, как будто вы хотите сериализацию вместо общей памяти? Если это действительно подходит для вашего приложения, способ сериализации будет зависеть от вашего языка. Если вы используете c ++, проверьте boost :: serialize. C #, несомненно, имеет много опций сериализации (например, Java), если вы это используете.

...