Такая ситуация. Есть файл достаточно сложной структуры, с которым постоянно работает приложение. Этот файл маппится в память и все замечательно все то время, пока файл находится на винте. Если же файл находится на сменном носителе (флешка, дискета, сидюк и т.д.) и этот носитель извлекается, то приложение очень нехорошо падает при попытке доступа к отмаппленной памяти. Перевести приложение на работу с файловыми функциями был бы оптимальный вариант, но сложно отследить все места, где требуется производить чтение-запись ( есть ли какой-нибудь автоматизированный способ??? ). try/except не рулят. Можете предложить какие-нибудь варианты решения проблемы?
Сделать обертку вокруг РеадФайл и ВрайтФайл, как это делает Борланд с функциями памяти, там есть запись с тремя адресами процедур аллока и освобождения памяти, которые можно заменить на свои, и все студийные классы + ГетМем и ФриМем проходят через эти функции.
Проблема в том, что функции не используются. Есть memory-mapped file и работает сейчас примерно так: Код (Text): void * file_projection; file_projection = create_file_mapping(); .... (char *) file_projection + 100 = 10; p = (any_struct *) file_projection->field1; .... p->fieldXXX++; .... flush_view_of_file(); // в критических местах кода При этом работают несколько потоков с достаточно простой синхронизацией. Получается, что нужно все переписывать?
Отследить вытаскивание носителя можно, обрабатывая сообщение WM_DEVICECHANGE. Хотя виндовс не должен позволить размонтировать флэшку с открытыми файлами, так что если юзер её выдернул в процессе работы с файлом - сам виноват. Для сохранения целостности данных можно работать с копией файла на винте, с периодической синхронизацией.
Во как Рихтер плохо действует на людей. Хотя я как то, то же к такому способу пришел до него, у меня было 1,7 Гб резервед памяти с которой необходимо было так работать , но из-за утечек памяти,( все структуры разнотипные и динамические ) от этого способа отказался. ------ ЗЫ : замени Код (Text): flush_view_of_file(); // в критических местах на: Код (Text): for (i=0;i<changed_pages;i++) { EnterCriticalSection(); SetFileptr(); WriteFile(ptrChangedPages[i]...); VirtualQuery(ptrChangedPages, защитить); LeaveSection(); } а в сехах : Код (Text): i++; ptrChangedPages.add(addrofexception&FFFF0000/*в зависимости от размера страницы*/); VirtualQuery(ptrChangedPages, снять_защиту);
green Виноват-то он виноват, а приложение падать не должно _Serega_ Попробую на основе твоего подхода отловить все обращения к памяти и заменить на файловые операции Сенкс
gilg Да, ничего, рад помочь, ведь друзья ЗЫ: тут вот подумал сех тож должен быть внутри критической секции, иначе - гонки.
Вообще надо перед началом думать о поддержке многопоточности, кривых девайсов и прочей ерунде - не придется потом морочаться. А тут досталось наследство... весь день убил ни за что Кстати, народ говорит, что во всех ОСях такая же проблема с мемори-маппингом. В юниксах приложение падает с segmentation fault. Интересно, существуют ли хотя бы в теории механизмы, как можно совместить удобство отображений в память с надежной работой?
Удобство отображения в память заканчивается тогда, когда требуется изменять размер структур и удалять их, в таком случае наступает полный трын-ц, а особенно тогда - когда эти структуры ссылаются друг на друга.