Разделяемая память Windows
От: Wavy  
Дата: 14.07.04 06:31
Оценка:
Предлагаю поговорить по этой теме, обменяться опытом.
Занимаюсь этим какое-то время, насобирал на свою голову мноо проблем.
В частности, интересует, как оставить возможной работу с указателями. Механизм, конечно, понятен — базовые указатели (хранящие сдвиг относительно начала маппинга), но решения могут быть разной степени удачности.. Кто-нибудь занимался этим?
... << RSDN@Home 1.1.3 stable >>
Re: Разделяемая память Windows
От: Carc Россия http://www.amlpages.com/home.php
Дата: 14.07.04 18:14
Оценка:
Здравствуйте, Wavy, Вы писали:

W>Предлагаю поговорить по этой теме, обменяться опытом.

W>Занимаюсь этим какое-то время, насобирал на свою голову мноо проблем.
W>В частности, интересует, как оставить возможной работу с указателями. Механизм, конечно, понятен — базовые указатели (хранящие сдвиг относительно начала маппинга), но решения могут быть разной степени удачности.. Кто-нибудь занимался этим?
Может быть какие-нить смарт-пойнтеры?
Aml Pages Home
Re: Разделяемая память Windows
От: King of a Stellar War Украина  
Дата: 14.07.04 21:29
Оценка:
Здравствуйте, Wavy, Вы писали:

W>Предлагаю поговорить по этой теме, обменяться опытом.

W>Занимаюсь этим какое-то время, насобирал на свою голову мноо проблем.
W>В частности, интересует, как оставить возможной работу с указателями. Механизм, конечно, понятен — базовые указатели (хранящие сдвиг относительно начала маппинга), но решения могут быть разной степени удачности.. Кто-нибудь занимался этим?

Меня тоже в данный момент интересует эта проблема. В моем проекте должный расшариваться в пределе около 100 кусков памяти, какждый из которых динамически может менять свой размер от едениц байт до 8МБ. Вот я и думаю как это сделать...У Р ихтера был описан способ с использованием резервирования через файл-меппинг и выделение через VirtualAlloc, я его еще не пробовал, но думаю при изменении размера блока будут тормоза из-за realloc`а...хотя фиг его знает
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re: Разделяемая память Windows
От: Аноним  
Дата: 14.07.04 22:00
Оценка:
Здравствуйте, Wavy, Вы писали:

W>Предлагаю поговорить по этой теме, обменяться опытом.

W>Занимаюсь этим какое-то время, насобирал на свою голову мноо проблем.
W>В частности, интересует, как оставить возможной работу с указателями. Механизм, конечно, понятен — базовые указатели (хранящие сдвиг относительно начала маппинга), но решения могут быть разной степени удачности.. Кто-нибудь занимался этим?

Как насчёт того, что бы почитать документацию по ключевому слову __based?
Re[2]: Разделяемая память Windows
От: Wavy  
Дата: 15.07.04 02:36
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Как насчёт того, что бы почитать документацию по ключевому слову __based?


Да, конечно же я видел эту документацию, но:
1. Microsoft Specific —>
2. Так получается, что каждый указатель занимает в 2 раза больше памяти (база и смещение).
3. Нельзя скопом сменить базу сразу для всех указателей.

Я сделал класс умных указателей, в котором база — статический член. И все бы хорошо, да вот только тогда нельзя работать в нескольких регионах сразу, а точнее — можно, но нужно менять базу каждый раз как только происходит обращение к другому региону. Невелик, конечно, труд, но довольно коряво..

У кого-нибудь есть другие идеи: чтобы без больших накладных расходов, чтобы была возможность быстрого переключения базы и одновременной работы с несколькими регионами?
... << Rsdn@Home 1.1.4 beta 1 >>
Re[2]: Разделяемая память Windows
От: Wavy  
Дата: 15.07.04 02:36
Оценка: 2 (1)
Здравствуйте, 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>У кого-нибудь есть другие идеи: чтобы без больших накладных расходов, чтобы была возможность быстрого переключения базы и одновременной работы с несколькими регионами?
Re[4]: Разделяемая память Windows
От: Wavy  
Дата: 15.07.04 10:04
Оценка:
Здравствуйте, <Аноним>, Вы писали:

W>>Здравствуйте, <Аноним>, Вы писали:


W>>1. Microsoft Specific —>

А>Это конечно серьезное возражение. Меня только интересует 1 вопрос. Разделяемая память Windows — это случаем не Microsoft Specific? То есть, зачем нужен общий код для работы с осыбыми возможностями?

Просто я юзаю борландовский компилер..

W>>2. Так получается, что каждый указатель занимает в 2 раза больше памяти (база и смещение).

А>Ну да, чудес не бывает. За всё приходится платить.

И все же чуда хочется.

W>>3. Нельзя скопом сменить базу сразу для всех указателей.


W>>Я сделал класс умных указателей, в котором база — статический член. И все бы хорошо, да вот только тогда нельзя работать в нескольких регионах сразу, а точнее — можно, но нужно менять базу каждый раз как только происходит обращение к другому региону. Невелик, конечно, труд, но довольно коряво..


А>Поделитесь кодом, может быть попробуем что-нибудь автоматизировать.


Кода шибко много, а идея и на словах видна, — вместе со всеми ее недостатками..
< Rsdn@Home 1.1.4 beta 1 >
Re[3]: Разделяемая память Windows
От: King of a Stellar War Украина  
Дата: 15.07.04 18:03
Оценка:
Здравствуйте, Wavy, Вы писали:

W>Я сделал именно так: резервирую крупный кусок (при этом физически память не расходуется), а потом выделяю по сколько нужно. Боле того, я сделал поверх большого куска динамическое выделение — написал свой менеджер кучи (стандартную виндовую кучу использовать почему-то не получилось, не помню почему).

W>В общем, рихтеровский способ работает, и тебе наверное лучше сделать именно так. А чтобы не было тормозов с реаллоком — попробуй просто выделять новый дополнительный кусочек в конец старого блока (не удаляя его), если твои данные можно организовать подходящим образом..

Кста, там у рихтера было написано:

WINDOWS 2000
В Windows 2000 функция VirtualFree не годится для возврата физической памяти, переданной в свос время проецируемому файлу (созданному с флагом SEC_RESERVE).

А чем тогда возвращять память???
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re[4]: Разделяемая память Windows
От: Wavy  
Дата: 16.07.04 02:15
Оценка:
Здравствуйте, King of a Stellar War, Вы писали:

KOA>Кста, там у рихтера было написано:


KOA>WINDOWS 2000

KOA>В Windows 2000 функция VirtualFree не годится для возврата физической памяти, переданной в свос время проецируемому файлу (созданному с флагом SEC_RESERVE).

KOA>А чем тогда возвращять память???


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

    hFileMap=CreateFileMapping((HANDLE)0xFFFFFFFF,            //create page file-mapping
                                NULL,                        //no security attr
                                PAGE_READWRITE|SEC_RESERVE,    //reserve memory range
                                0,                            //high-order size
                                Size,                        //low-order size
                                Name);                        //file-mapping name


Уже после того, как память зарезервирована, я ее выделяю по сколько нужно:

    VirtualAlloc(p, size, MEM_COMMIT, PAGE_READWRITE);


и удаляю вот так:

    VirtualFree(p, size, MEM_DECOMMIT);


Не утверждаю, что это единственно правильно и корректно, но это работает

Кстати, при выделении\освобождении памяти неплохо бы еще учитывать ее гранулярность. Дополнительно я завел обертки функций VirtualAlloc и VirtualFree, которые веделяют\освобождают память только постранично (по 4 к).
Вот.
< Rsdn@Home 1.1.4 beta 1 >
Re[5]: Разделяемая память Windows
От: King of a Stellar War Украина  
Дата: 27.07.04 21:21
Оценка:
Здравствуйте, Wavy, Вы писали:

W>Здравствуйте, King of a Stellar War, Вы писали:


KOA>>Кста, там у рихтера было написано:


KOA>>WINDOWS 2000

KOA>>В Windows 2000 функция VirtualFree не годится для возврата физической памяти, переданной в свос время проецируемому файлу (созданному с флагом SEC_RESERVE).

KOA>>А чем тогда возвращять память???


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

W>Я делаю так:

W>
W>    hFileMap=CreateFileMapping((HANDLE)0xFFFFFFFF,            //create page file-mapping
W>                                NULL,                        //no security attr
W>                                PAGE_READWRITE|SEC_RESERVE,    //reserve memory range
W>                                0,                            //high-order size
W>                                Size,                        //low-order size
W>                                Name);                        //file-mapping name
W>


W>Уже после того, как память зарезервирована, я ее выделяю по сколько нужно:


W>
W>    VirtualAlloc(p, size, MEM_COMMIT, PAGE_READWRITE);
W>


W>и удаляю вот так:


W>
W>    VirtualFree(p, size, MEM_DECOMMIT);
W>


W>Не утверждаю, что это единственно правильно и корректно, но это работает


W>Кстати, при выделении\освобождении памяти неплохо бы еще учитывать ее гранулярность. Дополнительно я завел обертки функций VirtualAlloc и VirtualFree, которые веделяют\освобождают память только постранично (по 4 к).

W>Вот.

Я у Рихтера об этом способе рашаривания куска памяти немного не понял:
1. Нужно ли вызывать MapViewOfFile после CreateFileMapping?
2. Что передавать в качестве первого операнда в VirtualAlloc?
3. Что делать с тем указателем, что возвращает VirtualAlloc?
4. Как мне освобождать память выделенную в другом процессе?
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re[6]: Разделяемая память Windows
От: Wavy  
Дата: 02.08.04 04:18
Оценка: 3 (1)
Здравствуйте, 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.
Эхх... Написать бы об этом все хаарошенькую такую статью...
Но некогда, ибо лень.
< Rsdn@Home 1.1.4 beta 1 >
Re[7]: Разделяемая память Windows
От: King of a Stellar War Украина  
Дата: 02.08.04 04:54
Оценка:
Здравствуйте, 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 г.
Re[8]: Разделяемая память Windows
От: Wavy  
Дата: 03.08.04 03:01
Оценка:
Здравствуйте, King of a Stellar War, Вы писали:

KOA>Я так понял, что адрес переданый в VirtualAlloc и полученный после его вызова, будут совпадать, если по этому адресу возможно разместить кусок памяти указанного размера? Иначе, система найдёт другую область?


Именно так.
Но кусок памяти линейный, работать с ним не очень удобно. Потому я и вспоминал про менеджер кучи.

KOA>>>4. Как мне освобождать память выделенную в другом процессе?

W>>С этим проблема. Чтобы освободить блок, выделенный другим процессом, нужно точно знать что он больше не используется и не будет использоваться тем процессом. Для этого можно ставить маркеры в блоках, но в любом случае, насколько мне известно, — без собственного менеджера памяти (кучи) тогда не обойтись.
W>>А освобождается память, насколько я понмню — VirtualFree.

KOA>А вот тут самое интересное, у меня по VirtualFree даже в родном процессе память не освобождается (ХР), перепробовал разные варианты, но память устойчиво освобождается только после вызова CloseHandle(hFileMapping)


Память выделяется\освобождается постранично. Если вызвать VirtualFree для целой страницы — разве тоже не освобождается?
< Rsdn@Home 1.1.4 beta 1 >
Re[9]: Разделяемая память Windows
От: King of a Stellar War Украина  
Дата: 03.08.04 21:44
Оценка:
Здравствуйте, Wavy, Вы писали:

W>Память выделяется\освобождается постранично. Если вызвать VirtualFree для целой страницы — разве тоже не освобождается?


Возможно я что-то делал не правильно, можно пример кода выделения/освобождения ?
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re[10]: Разделяемая память Windows
От: omb  
Дата: 18.11.07 22:16
Оценка:
> А вот тут самое интересное, у меня по 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, кросс-платформенные. Сам, правда, не щупал.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.