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метров ОЗУ!
Вопрос: Как считывать из ОЗУ не весь блок, а только длину полезной инфы в нем, если априори не известнос колько там в даннный момент этой инфы?
Солюшен номер один:
Еще на этапи записи/создания сегмента алокейтить ровно столько ОЗУ, сколько нужно записать полезной инфы... но в ПХП нет функции для изменения размера сегмента налету, т.е. потом при увеличении размера записываемой в ОЗУ инфы придется каждый раз убивать блок и создавать его заного в новым размером - это не есть правильно...
Задача тривиальная - считать 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метров ОЗУ!
Вопрос: Как считывать из ОЗУ не весь блок, а только длину полезной инфы в нем, если априори не известнос колько там в даннный момент этой инфы?
Солюшен номер один:
Еще на этапи записи/создания сегмента алокейтить ровно столько ОЗУ, сколько нужно записать полезной инфы... но в ПХП нет функции для изменения размера сегмента налету, т.е. потом при увеличении размера записываемой в ОЗУ инфы придется каждый раз убивать блок и создавать его заного в новым размером - это не есть правильно...