Казалась бы, обсуждаемая мной тема, мало кого волнует, но попытаемся разобраться в скрытых возможностях php, и чем эти возможности могут быть полезны разработчику. Тема PHP заезжена до дыр , о плюсах и минусах его сказано много , да вот проблема в том, что если недовольные хорошо знают все минусы данного языка программирования, то те, кому он нравится, плохо знают как можно оптимально его использовать. К сожалению, это очень портит репутацию PHP . Но тема не об этом.

Давайте представим простейшую задачу. Требуется сохранить информацию одним скриптом и считать его другим. Задача простейшая и многие сразу же крикнут: «Файлы, БД, COOKIE и т.д.». Давайте подумаем об эффективности данных подходов.

Начнем с файлов. Кратковременное сохранение данных в файле является мультиплатформенным решением, и даже в какой-то степени простым. Но с точки зрения оптимальности — это плохой вариант. Во-первых, сомнительно, что он окажется в кеше жесткого диска , значит считываться данные будут напрямую с носителя. Соответственно, жесткий диск может быть занят и своими более важными делами — значит получение данных будет задержано. Во-вторых, добавим к этому приоритетность задач, и тогда поймем, что временный файлик ваще важен только для вас , а для ОС он является самым последним в очереди.

Про Базы Данных можно долго спорить. Во-первых, надо еще соединиться с сервером БД, а это занимает очень много времени и ресурсов , ибо сервер БД — это отдельное приложение. Во-вторых, сервер БД может быть и так загружен, а тут еще вы со своим маленьким текстом.... Проблема не в том, что текст маленький, а в том, что надо инициализировать множество операций, чтобы этот текст передать и сохранить его в структуру таблиц БД. Лучше пусть БД занимается теми делами, в которых она лучше всего подходит: для хранения и выборки данных, а не для кратковременного хранения для передачи текста.

Про COOKIE скажу проще, во-первых, ограничение в 4 кб (хотя для краткого текста даже в UTF-8 этого предостаточно). Во-вторых, куки еще надо передать, а это несет в себе еще кучу операций. Да еще и данные идут через клиентскую часть, поэтому они могут быть сворованы или подделаны, или и то, и другое в порядке очередности =) . Да и куки могут быть отключены вааще, значит еще надо определять - включены они или нет, а это еще куча дополнительных тактов процессора будет съедено впустую.

Но если подумать — какой инструмент для ОПЕРАТИВНОЙ передачи данных мы забыли? По выделенному слову можно догадаться, что оперативного, т.е того источника, который быстро может предоставить информацию. Речь идет банально о системной памяти, которая чаще всего находится в области оперативной памяти, либо в виде файла подкачки, что быстрее в силу ряда причин (таких как структуры данных, приоритетность операций IO).

Но причем тут PHP ? А притом, что в PHP реализована работа с системной памятью на уровне ОС . Далее опишу, как можно использовать данную «примочку».

Для примера создадим два простейших скрипта: shm_write.php и shm_read.php, и посмотрим на их примере работу общей памяти. Задача состоит в том, чтобы записать информацию в память одним скриптом, а потом получить и вывести её другим скриптом.

--------------

shm_write.php

--------------

<?php

//Создадим ключ-идентификатор общей памяти (например 2008)

define('SHM_KEY', 2008);

//Создадим ключ-идентификатор хранящейся в памяти переменной (например 1430)

define('SHM_VAR_KEY', 1430);

//Укажем размер памяти выделяемой для хранения (для примера возьмем 1 кб)

define('SHM_MEMLIMIT', 1024);

//создаем идентификатор на общую память

$shm_mem = shm_attach(SHM_KEY, SHM_MEMLIMIT);

//сохраняем определенный текст в память

shm_put_var($shm_mem, SHM_VAR_KEY, 'Hello World');

//удаляем идентификатор на общую память (удаляется только идентификатор!)

shm_detach($shm_mem);

?>

------------------------------

shm_read.php

------------------------------

<?php

//Создадим ключ-идентификатор общей памяти (тот который мы указали в shm_write.php - 2008)

define('SHM_KEY', 2008);

//Создадим ключ-идентификатор хранящейся в памяти переменной ( тот который мы указали в shm_write.php - 1430)

define('SHM_VAR_KEY', 1430);

//создаем идентификатор на общую память

$shm_memory = shm_attach(SHM_KEY);

//обращаемся к сегменту памяти код ключом равным SHM_VAR_KEY и получаем хранимый текст

$message = shm_get_var($shm_memory, SHM_VAR_KEY);

//удаляем из памяти переменную под ключом SHM_VAR_KEY

shm_remove_var($shm_memory, SHM_VAR_KEY);

//удаляем общую память

shm_remove($shm_memory);

//выводим результат

echo $message;

?>

Запустим вначале shm_write.php - скрипт, который сохранит в сегмент памяти текст . А позднее запустим shm_read.php — скрипт, который прочитает текст из сегмента памяти.

На выводе мы получим «Hello World».

Всего пару строк кода, а мы смогли передать некую информацию из одного скрипта в другой, не задействовав ни внешний источник, ни файловую систему, ни базу данных.

Специального тестирования я проводить не стал, но судя по показаниям xDebug+KCacheGrind при симулированной нагрузке в 60% на одноядерный процессор, и при находящемся практически без дела жестаке, показало, что работа с системной памятью намного быстрее + не задевает тормозную файловую систему, да и хлама меньше. Я не стал проверять на системе с постоянной чтение-запись с жестким диском, но явно будет еще медленнее. Конечно, тест неявный, но зная, как работает системная память в unix системах, легко догадаться, что такая конструкция будет быстрее.

Так неужели нет минусов с использованием общей памяти в PHP ? Конечно, есть. Во-первых, это не кроссплатформенное решение (на Windows-серверах не будет работать). Во-вторых, надо не забывать память вычищать, иначе данные сохраненные в сегментах памяти останутся там до ближайшего рестарта сервера. Ну и в-третьих, администраторы не всегда любят использование общей памяти в нуждах скриптах, и для общих хостинговых систем поддержка SystemV может быть отключена, либо урезана по квоте.

С другой стороны, использование общей памяти SystemV (а также возможности установки прав доступа на сегмент, который по умолчанию равен 0666 — на чтение-запись) и механизма семафоров позволит реализовать монопольный доступ к сегментам памяти определенным скриптом. А это уже мощный контроллер против банальных backdoor и всяческих эксплоитов. Плюсом ко всему этому есть возможность передачи информации между процессами, не задействуя файловую систему.

О механизме семафоров я постараюсь написать в близжайшее время, а также привести примеры с совместным использованием семафоров и общей памяти.

____________________________

Похожие записи:


Теги: , , , , , ,

Комментарии (5) на запись “Семафоры и общая память System V в PHP”

  1. Евгений Шестаков пишет:

    Интересная статья. А как на счет поддержки System V на различных хостинг-площадках? Боюсь многие рубят эту возможность..
    Ждем про семафоры! :)

    [Ответить]

    Alligator Reply:

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

    [Ответить]

    Ivan_Fedorovich Reply:

    кстати тоже постоянно сталкиваюсь с темой зарубки System V на хостингах.....

    [Ответить]

  2. Евгений Шестаков пишет:

    Ну что там с семафорами, очень интересная тема!

    [Ответить]

  3. Repsnaree пишет:

    Интересная статья - а system v реально используется на ваших проектах?

    [Ответить]

Оставить комментарий