Предлагаю поговорить по этой теме, обменяться опытом.
Занимаюсь этим какое-то время, насобирал на свою голову мноо проблем.
В частности, интересует, как оставить возможной работу с указателями. Механизм, конечно, понятен — базовые указатели (хранящие сдвиг относительно начала маппинга), но решения могут быть разной степени удачности.. Кто-нибудь занимался этим?
Здравствуйте, Wavy, Вы писали:
W>Предлагаю поговорить по этой теме, обменяться опытом. W>Занимаюсь этим какое-то время, насобирал на свою голову мноо проблем. W>В частности, интересует, как оставить возможной работу с указателями. Механизм, конечно, понятен — базовые указатели (хранящие сдвиг относительно начала маппинга), но решения могут быть разной степени удачности.. Кто-нибудь занимался этим?
Может быть какие-нить смарт-пойнтеры?
Здравствуйте, Wavy, Вы писали:
W>Предлагаю поговорить по этой теме, обменяться опытом. W>Занимаюсь этим какое-то время, насобирал на свою голову мноо проблем. W>В частности, интересует, как оставить возможной работу с указателями. Механизм, конечно, понятен — базовые указатели (хранящие сдвиг относительно начала маппинга), но решения могут быть разной степени удачности.. Кто-нибудь занимался этим?
Меня тоже в данный момент интересует эта проблема. В моем проекте должный расшариваться в пределе около 100 кусков памяти, какждый из которых динамически может менять свой размер от едениц байт до 8МБ. Вот я и думаю как это сделать...У Р ихтера был описан способ с использованием резервирования через файл-меппинг и выделение через VirtualAlloc, я его еще не пробовал, но думаю при изменении размера блока будут тормоза из-за realloc`а...хотя фиг его знает
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re: Разделяемая память Windows
От:
Аноним
Дата:
14.07.04 22:00
Оценка:
Здравствуйте, Wavy, Вы писали:
W>Предлагаю поговорить по этой теме, обменяться опытом. W>Занимаюсь этим какое-то время, насобирал на свою голову мноо проблем. W>В частности, интересует, как оставить возможной работу с указателями. Механизм, конечно, понятен — базовые указатели (хранящие сдвиг относительно начала маппинга), но решения могут быть разной степени удачности.. Кто-нибудь занимался этим?
Как насчёт того, что бы почитать документацию по ключевому слову __based?
Здравствуйте, <Аноним>, Вы писали:
А>Как насчёт того, что бы почитать документацию по ключевому слову __based?
Да, конечно же я видел эту документацию, но:
1. Microsoft Specific —>
2. Так получается, что каждый указатель занимает в 2 раза больше памяти (база и смещение).
3. Нельзя скопом сменить базу сразу для всех указателей.
Я сделал класс умных указателей, в котором база — статический член. И все бы хорошо, да вот только тогда нельзя работать в нескольких регионах сразу, а точнее — можно, но нужно менять базу каждый раз как только происходит обращение к другому региону. Невелик, конечно, труд, но довольно коряво..
У кого-нибудь есть другие идеи: чтобы без больших накладных расходов, чтобы была возможность быстрого переключения базы и одновременной работы с несколькими регионами?
Здравствуйте, King of a Stellar War, Вы писали:
KOA>Меня тоже в данный момент интересует эта проблема. В моем проекте должный расшариваться в пределе около 100 кусков памяти, какждый из которых динамически может менять свой размер от едениц байт до 8МБ. Вот я и думаю как это сделать...У Р ихтера был описан способ с использованием резервирования через файл-меппинг и выделение через VirtualAlloc, я его еще не пробовал, но думаю при изменении размера блока будут тормоза из-за realloc`а...хотя фиг его знает
Я сделал именно так: резервирую крупный кусок (при этом физически память не расходуется), а потом выделяю по сколько нужно. Боле того, я сделал поверх большого куска динамическое выделение — написал свой менеджер кучи (стандартную виндовую кучу использовать почему-то не получилось, не помню почему).
В общем, рихтеровский способ работает, и тебе наверное лучше сделать именно так. А чтобы не было тормозов с реаллоком — попробуй просто выделять новый дополнительный кусочек в конец старого блока (не удаляя его), если твои данные можно организовать подходящим образом..
... << Rsdn@Home 1.1.4 beta 1 >>
Re[3]: Разделяемая память Windows
От:
Аноним
Дата:
15.07.04 09:56
Оценка:
Здравствуйте, Wavy, Вы писали:
W>Здравствуйте, <Аноним>, Вы писали:
А>>Как насчёт того, что бы почитать документацию по ключевому слову __based?
W>Да, конечно же я видел эту документацию, но: W>1. Microsoft Specific —>
Это конечно серьезное возражение. Меня только интересует 1 вопрос. Разделяемая память Windows — это случаем не Microsoft Specific? То есть, зачем нужен общий код для работы с осыбыми возможностями?
W>2. Так получается, что каждый указатель занимает в 2 раза больше памяти (база и смещение).
Ну да, чудес не бывает. За всё приходится платить.
W>3. Нельзя скопом сменить базу сразу для всех указателей.
W>Я сделал класс умных указателей, в котором база — статический член. И все бы хорошо, да вот только тогда нельзя работать в нескольких регионах сразу, а точнее — можно, но нужно менять базу каждый раз как только происходит обращение к другому региону. Невелик, конечно, труд, но довольно коряво..
Поделитесь кодом, может быть попробуем что-нибудь автоматизировать.
W>У кого-нибудь есть другие идеи: чтобы без больших накладных расходов, чтобы была возможность быстрого переключения базы и одновременной работы с несколькими регионами?
Здравствуйте, <Аноним>, Вы писали:
W>>Здравствуйте, <Аноним>, Вы писали:
W>>1. Microsoft Specific —> А>Это конечно серьезное возражение. Меня только интересует 1 вопрос. Разделяемая память Windows — это случаем не Microsoft Specific? То есть, зачем нужен общий код для работы с осыбыми возможностями?
Просто я юзаю борландовский компилер..
W>>2. Так получается, что каждый указатель занимает в 2 раза больше памяти (база и смещение). А>Ну да, чудес не бывает. За всё приходится платить.
И все же чуда хочется.
W>>3. Нельзя скопом сменить базу сразу для всех указателей.
W>>Я сделал класс умных указателей, в котором база — статический член. И все бы хорошо, да вот только тогда нельзя работать в нескольких регионах сразу, а точнее — можно, но нужно менять базу каждый раз как только происходит обращение к другому региону. Невелик, конечно, труд, но довольно коряво..
А>Поделитесь кодом, может быть попробуем что-нибудь автоматизировать.
Кода шибко много, а идея и на словах видна, — вместе со всеми ее недостатками..
Здравствуйте, Wavy, Вы писали:
W>Я сделал именно так: резервирую крупный кусок (при этом физически память не расходуется), а потом выделяю по сколько нужно. Боле того, я сделал поверх большого куска динамическое выделение — написал свой менеджер кучи (стандартную виндовую кучу использовать почему-то не получилось, не помню почему). W>В общем, рихтеровский способ работает, и тебе наверное лучше сделать именно так. А чтобы не было тормозов с реаллоком — попробуй просто выделять новый дополнительный кусочек в конец старого блока (не удаляя его), если твои данные можно организовать подходящим образом..
Кста, там у рихтера было написано:
WINDOWS 2000
В Windows 2000 функция VirtualFree не годится для возврата физической памяти, переданной в свос время проецируемому файлу (созданному с флагом SEC_RESERVE).
А чем тогда возвращять память???
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Здравствуйте, King of a Stellar War, Вы писали:
KOA>Кста, там у рихтера было написано:
KOA>WINDOWS 2000 KOA>В Windows 2000 функция VirtualFree не годится для возврата физической памяти, переданной в свос время проецируемому файлу (созданному с флагом SEC_RESERVE).
KOA>А чем тогда возвращять память???
Если честно, я этому замечанию Рихтера не придал значения.. точнее, не заметил его вовсе и поэтому не стал беспокоиться
Я делаю так:
Не утверждаю, что это единственно правильно и корректно, но это работает
Кстати, при выделении\освобождении памяти неплохо бы еще учитывать ее гранулярность. Дополнительно я завел обертки функций VirtualAlloc и VirtualFree, которые веделяют\освобождают память только постранично (по 4 к).
Вот.
Здравствуйте, Wavy, Вы писали:
W>Здравствуйте, King of a Stellar War, Вы писали:
KOA>>Кста, там у рихтера было написано:
KOA>>WINDOWS 2000 KOA>>В Windows 2000 функция VirtualFree не годится для возврата физической памяти, переданной в свос время проецируемому файлу (созданному с флагом SEC_RESERVE).
KOA>>А чем тогда возвращять память???
W>Если честно, я этому замечанию Рихтера не придал значения.. точнее, не заметил его вовсе и поэтому не стал беспокоиться W>Я делаю так:
W>
W>Не утверждаю, что это единственно правильно и корректно, но это работает
W>Кстати, при выделении\освобождении памяти неплохо бы еще учитывать ее гранулярность. Дополнительно я завел обертки функций VirtualAlloc и VirtualFree, которые веделяют\освобождают память только постранично (по 4 к). W>Вот.
Я у Рихтера об этом способе рашаривания куска памяти немного не понял:
1. Нужно ли вызывать MapViewOfFile после CreateFileMapping?
2. Что передавать в качестве первого операнда в VirtualAlloc?
3. Что делать с тем указателем, что возвращает VirtualAlloc?
4. Как мне освобождать память выделенную в другом процессе?
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Здравствуйте, King of a Stellar War, Вы писали:
KOA>Я у Рихтера об этом способе рашаривания куска памяти немного не понял: KOA>1. Нужно ли вызывать MapViewOfFile после CreateFileMapping?
О да.
Кстати, я сначала делаю OpenFileMapping, чтобы выяснить — я создал маппинг или он уже был.
Если уже есть — делаю MapViewOfFile. Иначе — делаю CreateFileMapping и запоминаю, что это именно я создал маппинг.
KOA>2. Что передавать в качестве первого операнда в VirtualAlloc?
Адрес, по которому желательно разместить выделяемый блок. Или NULL (а может, какую-то константу...) если хочешь получить кусок по произвольному адресу. Кажется, в том же Рихтере написано, что это будет адрес самого нижнего свободного куска. MSDN рулит.
KOA>3. Что делать с тем указателем, что возвращает VirtualAlloc?
Это указатель на выделенную область памяти. Делай с ним что хочешь.
Можешь, например, привести его к (SomeClass*) — при условии что sizeof(SomeClass) == SizeOfAllocatedBlock, и пользоваться как простым объектом.
KOA>4. Как мне освобождать память выделенную в другом процессе?
С этим проблема. Чтобы освободить блок, выделенный другим процессом, нужно точно знать что он больше не используется и не будет использоваться тем процессом. Для этого можно ставить маркеры в блоках, но в любом случае, насколько мне известно, — без собственного менеджера памяти (кучи) тогда не обойтись.
А освобождается память, насколько я понмню — VirtualFree.
Если хочешь, могу тебе прислать кусочки своего кода.
P.S.
Эхх... Написать бы об этом все хаарошенькую такую статью...
Но некогда, ибо лень.
Здравствуйте, Wavy, Вы писали:
W>Здравствуйте, King of a Stellar War, Вы писали:
KOA>>2. Что передавать в качестве первого операнда в VirtualAlloc? W>Адрес, по которому желательно разместить выделяемый блок. Или NULL (а может, какую-то константу...) если хочешь получить кусок по произвольному адресу. Кажется, в том же Рихтере написано, что это будет адрес самого нижнего свободного куска. MSDN рулит.
KOA>>3. Что делать с тем указателем, что возвращает VirtualAlloc? W>Это указатель на выделенную область памяти. Делай с ним что хочешь. W>Можешь, например, привести его к (SomeClass*) — при условии что sizeof(SomeClass) == SizeOfAllocatedBlock, и пользоваться как простым объектом.
Я так понял, что адрес переданый в VirtualAlloc и полученный после его вызова, будут совпадать, если по этому адресу возможно разместить кусок памяти указанного размера? Иначе, система найдёт другую область?
KOA>>4. Как мне освобождать память выделенную в другом процессе? W>С этим проблема. Чтобы освободить блок, выделенный другим процессом, нужно точно знать что он больше не используется и не будет использоваться тем процессом. Для этого можно ставить маркеры в блоках, но в любом случае, насколько мне известно, — без собственного менеджера памяти (кучи) тогда не обойтись. W>А освобождается память, насколько я понмню — VirtualFree.
А вот тут самое интересное, у меня по VirtualFree даже в родном процессе память не освобождается (ХР), перепробовал разные варианты, но память устойчиво освобождается только после вызова CloseHandle(hFileMapping)
W>Если хочешь, могу тебе прислать кусочки своего кода.
Спасибо, было бы неплохо
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Здравствуйте, King of a Stellar War, Вы писали:
KOA>Я так понял, что адрес переданый в VirtualAlloc и полученный после его вызова, будут совпадать, если по этому адресу возможно разместить кусок памяти указанного размера? Иначе, система найдёт другую область?
Именно так.
Но кусок памяти линейный, работать с ним не очень удобно. Потому я и вспоминал про менеджер кучи.
KOA>>>4. Как мне освобождать память выделенную в другом процессе? W>>С этим проблема. Чтобы освободить блок, выделенный другим процессом, нужно точно знать что он больше не используется и не будет использоваться тем процессом. Для этого можно ставить маркеры в блоках, но в любом случае, насколько мне известно, — без собственного менеджера памяти (кучи) тогда не обойтись. W>>А освобождается память, насколько я понмню — VirtualFree.
KOA>А вот тут самое интересное, у меня по VirtualFree даже в родном процессе память не освобождается (ХР), перепробовал разные варианты, но память устойчиво освобождается только после вызова CloseHandle(hFileMapping)
Память выделяется\освобождается постранично. Если вызвать VirtualFree для целой страницы — разве тоже не освобождается?
Здравствуйте, Wavy, Вы писали:
W>Память выделяется\освобождается постранично. Если вызвать VirtualFree для целой страницы — разве тоже не освобождается?
Возможно я что-то делал не правильно, можно пример кода выделения/освобождения ?
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
> А вот тут самое интересное, у меня по VirtualFree даже в родном процессе память не освобождается (ХР), перепробовал > разные варианты, но память устойчиво освобождается только после вызова CloseHandle(hFileMapping)
Поддерживаю тему, обнаружил у себя на XP именно такие симптомы, рыщу по инету уже пол дня, ответа пока нет.
Корректно работает только такой вариант:
PAGE_WRITECOPY — на CreateFileMapping + FILE_MAP_COPY на MapViewOfFile. Здесь образ создается нормально, т.е. при необходимости, можно сразу открыть окошко маппингом, записать в него что нужно, закрыть, при этом адрес маппинга автоматически отображается в адресное пространство процесса, а выделяемая память корректно освобождается при закрытии view, но данные не сбрасываются обратно в образ(видимо этот вариант годится только для чтения).
Если вручную мепировать view с помощью VirtualAlloc, то ни MEM_DECOMMIT, ни MEM_RELEASE не работают, VirtualFree возвращается c FALSE и GetLastError возвращает нечто вроде "неверный параметр" или "адрес неверный" причем пробовал разными способами: передавал корректный размер региона, выравнивал адреса по странице, по гранулярности, передавал 0 в Size, чтобы освободить весь регион(MSDN). НЕ РАБОТАЕТ!!! А ведь задумано так хорошо.
Буду пробовать сначала распределять вирт. память, а уж потом мепировать в неё view, с помощью MapViewOfFileEx, мож сработает(не уверен, что сработает), уж не знаю что и делать еще.
Re[4]: Разделяемая память Windows
От:
Аноним
Дата:
20.11.07 14:32
Оценка:
Здравствуйте, Аноним, Вы писали:
А> Разделяемая память Windows — это случаем не Microsoft Specific? То есть, зачем нужен общий код для работы с осыбыми возможностями?
Memory-mapped files есть в Boost, кросс-платформенные. Сам, правда, не щупал.