Сделать ZVAL постоянным в SAPI?

ZVAL обычно создается с помощью emalloc, поэтому он уничтожается в конце запроса страницы. Есть ли способ взять существующий ZVAL и сохранить его в SAPI (эквивалент pemalloc)? Как насчет создания ZVAL с помощью pemalloc?

В идеале я хотел бы сделать (в PHP-коде):

class Object
{
    public $foo;
}

if(!($object = persist("object")))
{
   $object = persist("object", new Object());
}

$object->foo[] = "bar";

print count($object->foo);

При каждом запросе count будет возвращать +1 (при условии, что каждый раз используется один и тот же «рабочий» PHP - я использую PHP-FPM).


person Luke    schedule 03.04.2012    source источник
comment
Интересное замечание: мы решили сменить платформу. Теперь мы будем использовать Go.   -  person Luke    schedule 16.09.2012
comment
Прохладный. Не могли бы вы уточнить причины? Сам смотрю на go, было бы неплохо узнать мотивы других людей.   -  person Flavius    schedule 16.09.2012
comment
Нам нужен активный экземпляр приложения. Нам также нужно было параллельное выполнение. Мы также оценили Node и Java. Node является однопоточным и использует асинхронную модель. В Java используется традиционная модель многопоточности (сложная). Go делает параллельное выполнение чрезвычайно простым и имеет ряд других полезных функций. Лучше всего Go компилируется, но обладает гибкостью языка сценариев. Это получает большую тягу. Он новый, но мы посчитали, что он как минимум быстрее PHP :).   -  person Luke    schedule 16.09.2012


Ответы (2)


По сути, вы описываете http://lxr.php.net/opengrok/xref/PHP_5_3/ext/sysvshm/sysvshm.c#242

Самое близкое, что вы можете получить без дублирования функций, которые уже есть в shm, это https://github.com/flavius/php-persist. Подвох: в prefork/многопроцессорном SAPI (например, в apache) разные запросы от одного и того же клиента могут попадать в разные процессы, и поэтому вы увидите разные данные (попробуйте на Linux + Firefox с жестким обновлением каждый раз в браузере).

Примечание: это незавершенная работа, в настоящее время сохраняется только целое число. Добавление массива должно быть тривиальным. Патчи приветствуются. Ему по-прежнему нужна часть десериализации и фактическое использование первого параметра persist().

person Flavius    schedule 04.04.2012
comment
Это на самом деле нормально. Ему не нужно сохраняться в разных процессах/потоках. Цель состоит в том, чтобы определенные объекты были предварительно загружены, чтобы их не приходилось каждый раз инициализировать. - person Luke; 04.04.2012
comment
Что, если бы я сохранил ссылку на родительский zval и пометил ее как постоянную или скопировал перед завершением запроса. Это должно сработать, я просто не знаю, как сделать существующий zval постоянным. Я знаю, что могу создать новый постоянный zval с помощью макроса ALLOC_PERMANENT_ZVAL. - person Luke; 04.04.2012
comment
Что такое родительский zval? В любом случае, это не сработает, потому что zval тем временем может исчезнуть или, что еще хуже, его может заменить другой zval (так что, если вам повезет, вы можете получить другое значение в своем zval, если нет, вы' получу segfault). - person Flavius; 04.04.2012
comment
В моем примере это $object. По сути, я думаю, что могу увеличить счетчик ссылок на 1 и отслеживать zval в хеш-таблице. Затем в расширении запроса выключения сделайте так, чтобы zval сохранялся, либо пометив его и его дочерние элементы как постоянные, либо сделав глубокую копию с помощью permalloc. Если кто-то перезапишет $object или он выйдет за пределы области видимости, это не должно вызывать беспокойства — увеличенный счетчик ссылок не позволит ему быть gc'd. Он отслеживает только zval, помещенный в функцию persist(). После этого переменная $object не имеет значения. Тем не менее, изменения в дочерних элементах шкалы должны быть зафиксированы. - person Luke; 04.04.2012
comment
@ Люк, я реализовал твою идею, часть десериализации еще предстоит выполнить. Работает только с одним zval*. Если вы заинтересованы, не стесняйтесь присылать запросы на включение. Удачи! - person Flavius; 05.04.2012
comment
Похоже, единственный способ - это сериализация. Могут быть и другие варианты предварительной загрузки классов фреймворка. См. обсуждение списка рассылки по внутренним вопросам: marc.info/?t=133375615000001&r=1&w=2 - person Luke; 10.04.2012

zend_object не может быть постоянным, поэтому вы не можете этого сделать. расширения, такие как APC, сериализуют объект в память.

person c9s    schedule 05.09.2015