Возможно вы искали: 'Grand Theft Auto: San ...'

May 31 2025 02:15:22
  • Как сделать 8Gamers.Ru домашней страницей?
  • Игры
    • База данных по играх
    • Игровые новости
    • Игровая индустрия
    • Обзоры на игры
    • Прохождения игр
    • Гайды к играм
    • Превью о играх
    • Игровые тизеры
    • Игровые арты
    • Игровые обои
    • Игровые скриншоты
    • Игровые обложки
    • Игровые трейлеры
    • Игровое видео
    • Вышедшие игры
    • Ближайшие релизы игр
  • Кино и ТВ
    • База данных по кино
    • Статьи о кино
    • Постеры
    • Кадры из кино
    • Кино трейлеры
    • Сегодня в кино
    • Скоро в кино
  • Комиксы и манга
    • Манга по алфавиту
    • База данных по комиксах
    • Читать онлайн комиксы
    • Читать онлайн манга
    • База персонажей
  • Читы и коды
    • Чит-коды для PC игр
    • Чит-коды для консольных игр
    • Трейнеры
    • Коды Game Genie
  • Моддинг
    • Модификации
    • Карты к играм
    • Программы для моддинга
    • Статьи о моддинге
  • Геймдев
    • Всё о создании игр
    • Список движков
    • Утилиты в помощь игроделу
    • Конструкторы игр
    • Игровые движки
    • Библиотеки разработки
    • 3D-модели
    • Спрайты и тайлы
    • Музыка и звуки
    • Текстуры и фоны
  • Рецензии
    • Игры
    • Кино
    • Аниме
    • Комиксы
    • Мангу
    • Саундтреки
  • Саундтреки
    • Лирика
  • Файлы
    • Патчи к играм
    • Русификаторы к играм
    • Сохранения к играм
    • Субтитры к кино
  • Медиа
    • Видео
    • Фото
    • Аудио
    • Фан-арты
    • Косплей
    • Фото с виставок
    • Девушки из игр
    • Рисунки
    • Рисуем онлайн
    • Фотохостинг
  • Юмор
    • Анекдоты
    • Афоризмы
    • Истории
    • Стишки и эпиграммы
    • Тосты
    • Цитаты
  • Флеш
    • Азартные
    • Аркады
    • Бродилки
    • Гонки
    • Для девочек
    • Для мальчиков
    • Драки
    • Квесты
    • Леталки
    • Логические
    • Мультфильмы
    • Открытки
    • Приколы
    • Разное
    • Спорт
    • Стратегии
    • Стрелялки
Статистика

Статей: 87772
Просмотров: 96425698
Игры
Injustice:  Gods Among Us
Injustice: Gods Among Us
...
Dark Souls 2
Dark Souls 2
Dark Souls II - вторая часть самой хардкорной ролевой игры 2011-2012 года, с новым героем, сюжето...
Battlefield 4
Battlefield 4
Battlefield 4 - продолжение венценосного мультиплеер-ориентированного шутера от первого ли...
Кино
Steins;Gate
Steins;Gate
Любители японской анимации уже давно поняли ,что аниме сериалы могут дать порой гораздо больше пи...
Ку! Кин-дза-дза
Ку! Кин-дза-дза
Начинающий диджей Толик и всемирно известный виолончелист Владимир Чижов встречают на шумной моск...
Обзоры на игры
• Обзор Ibara [PCB/PS2] 18407
• Обзор The Walking ... 18853
• Обзор DMC: Devil M... 19921
• Обзор на игру Valk... 15921
• Обзор на игру Stars! 17810
• Обзор на Far Cry 3 18000
• Обзор на Resident ... 16063
• Обзор на Chivalry:... 17561
• Обзор на игру Kerb... 18021
• Обзор игры 007: Fr... 16667
Превью о играх
• Превью к игре Comp... 18003
• Превью о игре Mage... 14502
• Превью Incredible ... 14763
• Превью Firefall 13523
• Превью Dead Space 3 16378
• Превью о игре SimC... 14772
• Превью к игре Fuse 15479
• Превью Red Orche... 15589
• Превью Gothic 3 16388
• Превью Black & W... 17402
Главная » Статьи » Разное » Использование разделяемой памяти в PHP (php ipc memory share)

Использование разделяемой памяти в PHP (php ipc memory share)

Ключевые слова: php, ipc, memory, share, (найти похожие документы)

From: Alexander Prohorenko, Перевод: Крушняков Кирилл
Newsgroups: http://detail.phpclub.ru
Date: Mon, 20 Apr 2005 18:21:07 +0000 (UTC)
Subject: Использование разделяемой памяти в PHP

Оригинал: http://detail.phpclub.ru/article/shared_memory
http://www.onlamp.com/pub/a/php/2004/05/13/shared_memory.html


IPC ("Inter-Process Communication" - межпроцессное взаимодействие) -
одна из важнейших особенностей ОС семейства UNIX. Она позволяет
различным процессам взаимодействовать между собой. В этой статье речь
пойдёт о двух технологиях System V IPC (System V - одна из ключевых
версий ОС UNIX компании AT&T - прим. пер.): о семафорах и разделяемой
памяти. System V IPC впервые появилась в SVR2 (System V Release 2 -
прим. пер.). System V IPC, однако, была реализована многими
разработчиками. Она также доступна в SVR4.

Концепция IPC слагается из нескольких компонентов. Термин
подразумевает различные механизмы обмена данными между процессами,
стартовавшими в одной системе. IPC позволяет избежать создания
огромного приложения с большим набором функций всех различных
назначений и заменить его на использование отдельных, малых
приложений, способных обмениваться данными между собой. Традиционный
подход Unix заключается в том, чтобы позволить многопроцессорным
ситемам запускать приложения в отдельных процессах (threads) для
сокращения времени, требуемого на выполнение специфических задач.

На высоком уровне мы можем разделить межпроцессное взаимодействие на
следующие наиболее крупные и важные разделы:
* Сообщения: каналы (pipes) и очереди сообщений (pipes and message
queues)
* Разделяемая память (Shared memory)
* Удаленный вызов процедур - RPC (remote procedure calls)
* Синхронизация: семафоры и любые виды блокирования
* Сетевое взаимодействие (API сокетов)

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


Идентификаторы IPC

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

Учтите, что идентификатор объекта IPC является уникальным только для
одного типа объектов. Другими словами, только одна очередь сообщений
может иметь идентификатор 12345, хотя номер 12345 может также
использоваться семафорами и/или сегментами разделенной памяти.


Ключи IPC

Как создается идентикфикатор IPC? Для этого необходим ключ. Первым
шагом при создании среды взаимодействия между приложениями является
координирование использования ключей. Представьте себе это так: для
того, чтобы позвонить кому-либо, вы должны знать его телефонный номер.
Телефонная компания должна знать, как переслать ваш звонок абоненту. И
только, когда он отвечает, происходит соединение.

В случае применения System V IPC "телефон" соединяет объекты одного
типа. Телефонной компанией или способом маршрутизации является "ключ"
IPC.

Приложения должны генерировать свои собственные ключи. Фунция ftok()
делает это и для клиента и для сервера. Значение ключа, возвращаемое
функцией ftok(), зависит от значения inode и младшего значения
идентификатора устройства для первого аргумента - файла - и символа -
второго аргумента. Это не обеспечивает уникальности, но приложения
могут проводить проверки на предмет коллизий и генерировать новые
ключи по мере необходимости.

key_t mykey;
mykey = ftok ("/tmp/myapp", 'a');


В примере, приведенном выше, директория /tmp/myapp комбинируется с
литеральным идентификатором a для генерации ключа. Другим
распространенным примером является использование текущей директории:

key_t mykey;
mykey = ftok(".", 'a');


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

Следующие системные вызовы IPC используют значение возвращаемого ключа
для создания или изменения доступа к объектам IPC.

Команда ipcs отображает состояние всех объектов System V IPC.
ipcs -q: показывать только очереди сообщений
ipcs -s: показывать только семафоры
ipcs -m: показывать только разделяемую память
ipcs --help: для любознательных

По умолчанию показываются все три категории объектов. Рассмотрим
пример простейшего вывода команды ipcs:

------ Shared Memory Segments --------
shmid owner perms bytes nattch status
------ Semaphore Arrays --------
^semid owner perms nsems status
------ Message Queues --------
msqid owner perms used-bytes messages
0 root 660 5 1


Мы видим единственную очередь сообщений с идентификатором 0. Она
принадлежит пользователю root и обладает правами доступа 660, или
-rw-rw---. Очередь содержит одно 5-тибайтовое сообщение.

Команда ipcs является мощным механизмом для мониторинга памяти ядра
объектов IPC.


Команда ipcrm.

ipcrm удаляет объекты IPC из ядра. Однако, поскольку объекты IPC могут
быть удалены с помощью системных вызовов из прикладной программы,
необходимость удалять их вручную возникает редко. Команда очень
простая:

ipcrm - type (тип) id (номер)


Необходимо обозначить тип удаляемого объекта параметром. Обратитесь за
подробностями к справке man. Идентификатор IPC можно определить с
помощью команды ipcs. Помните, что идентификатор уникален только для
объектов одного типа. Вот почему необходимо указывать тип объекта при
его удалении.


Семафоры.

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

Этот механизм также обеспечивает функции для работы с разделяемой
памятью System V. Разделяемая память обеспечивает доступ к глобальным
переменным для различных процессов. Демоны httpd и даже другие
программы (на Perl, C и других языках) могут получить доступ к этим
данным с целью глобального обмена данными. Помните, однако, что
разделяемая память не защищена от одновременного доступа.

Таблица 1 демонстрирует переменные Unix, которые определяют параметры
ограничений разделяемой памяти. Каждый подвид Unix обладает своей
документаций по этим переменным. К примеру, во FreeBSD они являются
частью конфигурации ядра. Вам потребуется перекомпилировать ядро для
принятия изменений.

Table 1. Переменные разделяемой памяти Unix
SHMMAX Максимальное количество разделяемой памяти, обычно 131072 байт
SHMMIN Минимальное количество разделяемой памяти, обычно 1 байт
SHMMNI Максимальное количество сегментов разделяемой памяти в системе,
обычно 100
SHMSEG Максимальное количество сегментов разделяемой памяти для одного
процесса, обычно 6

Функции сообщений могут посылать сообщения одним процессам и принимать
сообщения от других. Они являются простым и эффективным способом
обмена данными между процессами без необходимости использования
системы сокетов Unix.


Использование разделяемой памяти и семафоров

Изучая что-то новое, каждый разработчик хочет начать использовать эту
технологию на практике, хотя бы написав простую программу "Hello,
world!". Это нормально, поэтому приведем минимальные сведения,
необходимые для того, чтобы вы могли создать этот простой тестовый
пример.

Разделяемая память является быстрейшим видом IPC, но она требует
синхронизации между сохранением и извлечением данных. Каков же тогда
алгоритм использования разделяемой памяти? Попросту говоря, он
заключается в следующем:
* Получить доступ к разделяемой памяти, используя семафор.
* Записать данные в сегмент разделяемой памяти.
* После завершения записи уведомить об этом другие программы,
используя семафор.

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

Теперь возникает вопрос, как использовать семафор. На самом деле это
весьма просто и понятно из приведенного примера кода. Единственная
тонкость заключается в том, что, поскольку семафоры могут блокировать
и разблокировать ресурсы, они также могут блокировать друг друга. Без
аккуратного проектирования процессы могут попытаться овладеть одним и
тем же семафором одновременно, вызывая долгие задержки при ожидании
доступа. И, даже при должном проектировании, всегда будет верхний
предел производительности в мультипроцессорных системах. За
подробностями обратитесь к любой книге, посвященной многопроцессорным
системам.

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

int sem_get (int key [, int max_acquire [, int perm]])


Эта функция возвращает id семафора. Он будет положительным в случае
успеха и равен FALSE в случае ошибки. Используйте id для доступа к
семафору V с помощью ключа key.

Если это необходимо, семафор может обладать правами доступа,
указанными в параметре perm. Значение по умолчанию: 0666. Параметр
max_acquire управляет количеством процессов, которые могут
одновременно получить доступ к семафору. По умолчанию он равен 1.

Вторичный вызов функции sem_get() для того же ключа вернет другой id,
но они оба будут указывать на один и тот же семафор.

bool sem_acquire(int sem_identifier)


Эта функция возвращает TRUE в случае успеха и FALSE при неудаче. Она
заблокируется, если необходимо, до тех пор, пока не займет запрошенный
семафор. Процесс попытки занять запрошенный семафор будет длиться
бесконечно, если он превысит значение параметра max_acquire.

Все семафоры, используемые в процессе, но не освобожденные явно, будут
закрыты автоматически. Однако, это породит предупреждение.

int shm_attach(int key [, int memsize [, int perm]])


Эта функция создает или открывает сегмент разделяемой памяти.
shm_attach() возвращает идентификатор для использования при получении
доступа к сегменту с помощью заданного ключа. Размер сегмента в байтах
будет равен mem_size. Значение по умолчанию равно sysvshm. init_mem в
файле конфигурации PHP (или 10,000 байт, если оно не установлено в
файле). Необязательный параметр perm определяет права доступа и равен
0666 по умолчанию.

Первый вызов с заданным ключом создаст сегмент. Второй вызов с тем же
ключом вернет другой идентификатор, игнорируя два других параметра.
Оба идентификатора предоставляют доступ к одному и тому же сегменту
разделяемой памяти.

mixed shm_get_var(int id, int variable_key)


Эта функция возвращает переменную, идентифицируемую параметром
variable_key, из сегмента разделяемой памяти с идентификатором id.
Переменная остается в разделяемой памяти.

int shm_put_var(int shm_identifier, int variable_key, mixed variable)


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

bool sem_release(int sem_identifier)


Эта функция освобождает семафор, если он занят текущим процессом. В
противном случае выдает предупреждение (warning). Возвращает TRUE в
случае успеха и FALSE в случае ошибки.

После освобождения семафора для того, чтобы его повторно использовать,
вызовите sem_acquire().

int shm_remove(int shm_identifier)


Эта функция удаляет сегмент разделяемой памяти и все содержащиеся в
нем данные.

bool sem_remove(int sem_identifier)


Эта функция удаляет семафор, заданный с помощью sem_identifier, если
он был создан с помощью sem_get. Возвращает TRUE в случае успеха и
FALSE в случае ошибки. Если семафора с указанным идентификатором не
существует, она породит предупреждение (warning). После удаления
семафор недоступен.


Образец кода, использующего разделяемую память

Вот образец кода, использующего разделяемую память, с попутными
комментариями:

<?php
MEMSIZE = 512; // объём выделяемой разделяемой памяти
$SEMKEY = 1; // ключ семафора
$SHMKEY = 2; // ключ разделяемой памяти
echo "Старт.n";
// Создаем семафор
$sem_id = sem_get($SEMKEY, 1);
if ($sem_id === false)
{
echo "Ошибка при создании семафора";
exit;
}
else
echo "Создан семафор $sem_id.n";
// Занимаем семафор
if (! sem_acquire($sem_id))
{
echo "Ошибка при попытке занять семафор $sem_id.n";
sem_remove($sem_id);
exit;
}
else
echo "Успешно занят семафор $sem_id.n";
// Подключаем разделяемую память
$shm_id = shm_attach($SHMKEY, $MEMSIZE);
if ($shm_id === false)
{
echo "Ошибка при подключении разделяемой памяти.n";
sem_remove($sem_id);
exit;
}
else
echo "Успешное подключение разделяемой памяти: $shm_id.n";
// Пишем переменную 1
if (!shm_put_var($shm_id, 1, "Переменная 1"))
{
echo "Ошибка при попытке записать переменную 1 в разделяемую память $shm_id.n";
// Овобождаем ресурсы.
sem_remove($sem_id);
shm_remove($shm_id);
exit;
}
else
echo "Переменная 1 записана в разделяемую память.n";
// Пишем переменную 2
if (!shm_put_var($shm_id, 2, "Переменная 2"))
{
echo "Ошибка при попытке записать переменную 2 в разделяемую память $shm_id.n";
// Овобождаем ресурсы.
sem_remove($sem_id);
shm_remove ($shm_id);
exit;
}
else
echo "Переменная 2 записана в разделяемую память.n";
// Читаем переменную 1
$var1 = shm_get_var($shm_id, 1);
if ($var1 === false)
{
echo "Ошибка при попытке прочитать переменную 1 из разделяемой памяти $shm_id, " .
"возвращенное значение=$var1.n";
}
else
echo "Прочитана переменная 1=$var1.n";
// Читаем переменную 2
$var2 = shm_get_var ($shm_id, 2);
if ($var1 === false)
{
echo "Ошибка при попытке прочитать переменную 2 из разделяемой памяти $shm_id, " .
"возвращенное значение=$var2.n";
}
else
echo "Прочитана переменная 2=$var2.n";
// Освобождаем семафор
if (!sem_release($sem_id))
echo "Ошибка при попытке освободить семафор $sem_id.n";
else
echo "Семафор $sem_id освобожден.n";
// Удаляем сегмент разделяемой памяти
if (shm_remove ($shm_id))
echo "Сегмент разделяемой памяти успешно удален.n";
else
echo "Ошибка при попытке удалить сегмент разделяемой памяти
$shm_id.n";
// Удаляем семафор.
if (sem_remove($sem_id))
echo "Семафор успешно удален.n";
else
echo "Ошибка при попытке удалить семафор $sem_id.n";
echo "Конец.n";
?>


Вот пример кода, выполняющего различные операции с разделяемой
памятью:

<?php
// Создаем блок разделяемой памяти размером 100 байт и с идентификатором равным 0xff3
$shm_id = shmop_open(0xff3, "c", 0644, 100);
if(!$shm_id)
{
echo "Ошибка при создании сегмента разделяемой памяти.n";
}
// Получаем размер сегмента разделяемой памяти
$shm_size = shmop_size($shm_id);
echo "Блок разделяемой памяти с размером: ". $shm_size . " создан.n";
// Пишем тестовую строку в сегмент разделяемой памяти
$shm_bytes_written = shmop_write($shm_id, "Мой блок разделяемой памяти", 0);
if($shm_bytes_written != strlen("Мой блок разделяемой памяти"))
{
echo "Ошибка при попытке записать данные полностьюn";
}
// Считываем записанную строку
$my_string = shmop_read($shm_id, 0, $shm_size);
if(!$my_string)
{
echo "Ошибка при попытке чтения разделяемой памятиn";
}
echo "Данные в разделяемой памяти равны: ".$my_string."n";
// Удаляем блок и закрываем сегмент разделяемой памяти
if(!shmop_delete($shm_id))
{
echo "Ошибка при попытке пометить блок разделяемой памяти на удаление.";
}
shmop_close($shm_id);
?>


Для более подробной информации об этих или других функциях обращайтесь
к официальной документации PHP (http://www.php.net/docs.php).
913 Прочтений •  [Использование разделяемой памяти в PHP (php ipc memory share)] [08.05.2012] [Комментариев: 0]
Добавил: Ukraine Vova
Ссылки
HTML: 
[BB Url]: 
Похожие статьи
Название Добавил Добавлено
• Использование разделяемой памяти в ... Ukraine Vova 08.05.2012
Ни одного комментария? Будешь первым :).
Пожалуйста, авторизуйтесь для добавления комментария.

Проект входит в сеть сайтов «8Gamers Network»

Все права сохранены. 8Gamers.NET © 2011 - 2025

Статьи
Рецензия на Pressure
Рецензия на Pressure
Чтобы обратить на себя внимание, начинающие маленькие разработчики, как правило, уходят в жанры, ...
Рецензия на Lost Chronicles of Zerzura
Рецензия на Lost Chron...
Игры, сделанные без любви и старания, похожи на воздушный шар – оболочка есть, а внутри пусто. Lo...
Рецензия на The Bridge
Рецензия на The Bridge
«Верх» и «низ» в The Bridge — понятия относительные. Прогуливаясь под аркой, можно запросто перей...
Рецензия на SimCity
Рецензия на SimCity
Когда месяц назад состоялся релиз SimCity, по Сети прокатилось цунами народного гнева – глупые ош...
Рецензия на Strategy & Tactics: World War 2
Рецензия на Strategy &...
Название Strategy & Tactics: World War II вряд ли кому-то знакомо. Зато одного взгляда на ее скри...
Рецензия на игру Scribblenauts Unlimited
Рецензия на игру Scrib...
По сложившейся традиции в информационной карточке игры мы приводим в пример несколько похожих игр...
Рецензия на игру Walking Dead: Survival Instinct, The
Рецензия на игру Walki...
Зомби и продукция-по-лицензии — которые и сами по себе не лучшие представители игровой биосферы —...
Обратная связь | RSS | Донейт | Статистика | Команда | Техническая поддержка