Advanced программинг: простой сложный вопрос по Shared Memory (shmop)

simplyAl

Новичок
Advanced программинг: простой сложный вопрос по Shared Memory (shmop)

Задача тривиальная - считать N байт из шаред мемори - точнее всю полезную инфу, что есть в сегменте.
Все происходит на пхп 5.2.0.

Итак, есть сегмент длиной 256кб. В него переодически пишется сериализованный массив длиной 30-60кб, размер сегмента в 256кб выбран с запасом, т.к. длина массива не постоянна и может увеличиваться в разы.

Дальше интересное. Делатю трейс использования памяти ПХП:

0.2396 786432 +0 -> shmop_read(22, 0, 262144) /mnt/hgfs/devel/hive/main.inc:165
0.2411 1310720 +524288 -> shmop_close(22) /mnt/hgfs/devel/hive/main.inc:166
0.2416 1310720 +0 -> unserialize('<..тут инфа...>') /mnt/hgfs/devel/hive/main.inc:167
0.3255 786432 -524288 -> microtime(TRUE) /mnt/hgfs/devel/dnet1.1/download/logix/gate_lib.inc:20
0.3260 786432 +0 -> count(<..тут инфа...>) /mnt/hgfs/devel/dnet1.1/download/logix/gate_lib.inc:23

Видно, что считывание сегмента длиной 256кб сожрало 512кб ОЗУ, т.е. ровно в раза больше чем размер сегмента. Но самое главное что полезной информации в сегменте всего 30кб! Т.е. shmop_read() вернула всего 30кб, почему ПХП сожрал 512кб?

Моя версия такая: видимо ПХП _всегда_ читает из ОЗУ блок полностью (256кб) и пото уже смотрит сколько в нем было инфы. Т.е. не важно сколько байт записано внутрь блока, блок всегда будет считан целиком! Значит, если у меня блок рамером 32 метра (!) с 30 кб полезной инфы и его параллельно читаю 10 процессов ПХП, тов сего нужно (2*32)*10=640метров ОЗУ!

Вопрос: Как считывать из ОЗУ не весь блок, а только длину полезной инфы в нем, если априори не известнос колько там в даннный момент этой инфы?

Солюшен номер один:
Еще на этапи записи/создания сегмента алокейтить ровно столько ОЗУ, сколько нужно записать полезной инфы... но в ПХП нет функции для изменения размера сегмента налету, т.е. потом при увеличении размера записываемой в ОЗУ инфы придется каждый раз убивать блок и создавать его заного в новым размером - это не есть правильно...
 

AnToXa

prodigy-одаренный ребенок
подсказка номер раз: память не копируется никуда. все процессы видят одну и ту же область памяти и разделяют ее, отсюда и название shared memory.
 

simplyAl

Новичок
AnToXa
я в курсе что такое Shared Memory и с чем это едят.
ты не понял вопроса. сам ПХП алокейтит память для себя при опирации считывания из шаред мемори.
 

AnToXa

prodigy-одаренный ребенок
при операции считывания, т.е. [m]shmop_read[/m], да аллокейтит, копирует кусок данных размера как ты попросил в некоторую переменную.

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

hermit_refined

Отшельник
т.е. ровно в раза больше чем размер сегмента
насколько я помню исходники, мне это кажется странным.
видимо ПХП _всегда_ читает из ОЗУ блок полностью
shmop_read(22, 0, 262144) /mnt/hgfs/devel/hive/main.inc:165
сколько вы запрашиваете байт функцией shmop_read(), столько и получаете, PHP тут не виноват. хотите меньше - так просите меньше.
 

simplyAl

Новичок
hermit_refined
понятно, что я спрашиваю 256кб, но реально 226кб из них пустые - ПХП мог бы и видеть что бОльшая часть сегмента пустая и выделять памяти только под полезную часть.

т.е. $t=shmop_read(22, 0, 262144);
echo strlen($t);
выведет 30720

а памяти будет занято 512 кб. (а не 30720 байт)

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

AnToXa
насчет физической и вирт памяти - мысль понял.
 
Сверху