Рубрики
Uncategorized

PHP просто использует функции shmop для создания общей памяти, чтобы уменьшить нагрузку на сервер

Автор оригинала: David Wong.

Концепция общей памяти была объяснена в предыдущем блоге [Понимание концепций, преимуществ и недостатков общей памяти]. Вот простой способ использования общей памяти (на самом деле вы можете использовать другие инструменты, такие как redis)

PHP имеет два набора интерфейсов для совместного использования памяти. Один из них-shm, который на самом деле является общим доступом к переменным, который сериализует и хранит объектные переменные. Он прост в использовании, но сериализованное хранилище не имеет смысла для эффективных операций доступа к памяти. Другой – магазин, который является общим для Linux и Windows, но имеет более слабые функции, чем sham. В Linux эти функции напрямую реализуются путем вызова функций серии shm*, а в Windows тот же вызов достигается путем инкапсуляции системных функций. Сначала я пользуюсь магазином.

Чтобы создать сегмент общей памяти, нам нужно использовать функцию shmop, поэтому предпосылке необходимо открыть расширение, вы можете обратиться к [Открыть расширение shmop для PHP для достижения общей памяти].

Основные функции магазина

Shop_open (создание или открытие блоков общей памяти), shmop_write (запись данных в блоки общей памяти), shmop_read (чтение данных из блоков общей памяти), shmop_size (получение размера блоков общей памяти), shmop_close (закрытие блоков общей памяти), shmop_delete (удаление блоков общей памяти)

php
// Create a shared memory
$shm_key = 0x4337b101;
$shm_id = @shmop_open($shm_key, 'c', 0644, 1024);
// Read and write data
$data = shmop_read($shm_id, 0, 1024);
shmop_write($shm_id, json_encode($data), 0);
$size = shmop_size ($shm_id); // Get the actual data footprint in memory
// Close the memory block, not delete the shared memory, just clear the resources of PHP
shmop_close($shm_id);

Shop_open (создание сегментов памяти)

Первое, что появляется в этой функции, – это параметр system ID. Это номер, который идентифицирует сегмент общей памяти в системе. Второй параметр-это режим доступа, который очень похож на режим доступа функции fopen. Вы можете получить доступ к сегменту памяти в четырех различных режимах:

Режим “a”, который позволяет получить доступ к сегментам памяти только для чтения, режим доступа только для чтения “w”, который позволяет получить доступ к сегментам памяти для чтения и записи, режим чтения и записи “c”, который создает новый сегмент памяти, или, если сегмент памяти уже существует, пытается открыть его для чтения и записи Режим “n”, который создает новый сегмент памяти, не удается создать, если тот же ключ уже существует, ради безопасного использования общей памяти. Третий параметр – это разрешение сегмента памяти. Здесь вы должны указать восьмеричное значение.

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

Обратите внимание, что эта функция возвращает идентификационный номер, который другие функции могут использовать для управления сегментом общей памяти. Этот идентификатор является идентификатором доступа к общей памяти, который, в отличие от системного идентификатора, передается в качестве параметра. Пожалуйста, будьте осторожны, чтобы не перепутать их. Если это не удается, shop_open возвращает значение FALSE. При создании блоков памяти рекомендуется, чтобы ключевые параметры были константами, а не переменными, иначе возможны утечки памяти.

Shmoop_write (запись данных в сегменты памяти)

Эта функция аналогична функции fwrite, которая имеет два параметра: ресурс открытого потока (возвращаемый fopen) и данные, которые вы хотите записать. Функция shop_write также выполняет эту задачу.

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

Shmoop_read (считывание данных из сегмента памяти)

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

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

Это очень похоже на наше поведение в функции FREAD, которая принимает два параметра: ресурс открытого потока (возвращаемый fopen) и количество байтов, которые вы хотите прочитать из потока. Используйте функцию размера файла, которая возвращает количество байтов в файле, чтобы прочитать его полностью.

Размер магазина (возвращает фактический размер данных сегмента)

Например, мы создали пространство памяти длиной 100 байт, но фактическая длина хранимых данных составляет всего 90, поэтому значение, возвращаемое shmop_size, равно 90.

Shmop_delete (удаление сегментов памяти)

Функция принимает только один параметр: идентификатор общей памяти, который мы хотим удалить, который на самом деле не удаляет сегмент. Он помечает сегмент памяти как удаленный, поскольку сегмент общей памяти не может быть удален, когда его используют другие процессы. Функция shmop_delete помечает сегмент памяти как удаленный, предотвращая его открытие любым другим процессом. Чтобы удалить его, нам нужно закрыть сегмент памяти. При создании блоков памяти рекомендуется, чтобы ключевые параметры были константами, а не переменными, иначе возможны утечки памяти.

Shop_close (закрыть сегмент памяти)

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

Просмотр Простых Результатов Тестирования

Я работаю в среде SNMP, и если вы похожи на меня, вы можете использовать команду Linux для проверки адреса и размера занятости после выполнения простой операции.

# ipcs -m
[[email protected] ~]# ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x00000000 0              gdm              600                 393216            2         dest         
0x00000000 32769             gdm              600                 393216            2         dest                              
0x4337b101 884750           nobody         644                 1024                0       

Описание команды

Ключ: Уникальное значение ключа общей памяти, которое используется общей памятью для определения того, какую память вы читаете. Шмид: Когда вы используете ключ для получения памяти, вы получаете значение этого идентификатора. Он служит для идентификации блоков памяти, с которыми вы работаете. Владелец: Пользователь, создавший блок общей памяти Perms: Разрешения на чтение и запись в общей памяти, 8 запрещенных, могут быть 777, в соответствии с разрешениями на чтение и запись файла. Байты: Размер блока памяти Nattch: Количество процессов, подключающихся к блоку памяти Статус: Текущее состояние, например, dest, готовится к удалению и т.д.

Небольшой пример практического применения проекта

_memory_key, 'a', 0644, $this->_memory_size);  

    if ($shmid === FALSE) {
        $shmid = @shmop_open($this->_memory_key, 'c', 0644, $this->_memory_size);  
        $data = $this->return_skill_list();
        shmop_write($shmid, json_encode($data), 0); 
        @shmop_close($shmid);

        return $data;
    }
    $data = json_decode(preg_replace('/[\x00-\x1F\x80-\x9F]/u', '', trim(shmop_read($shmid, 0, $this->_memory_size))), true);
    @shmop_close($shmid);
    return $data;    
  
  }

  Public function return_skill_list() {// Here is a very large array, which is actually jsonized and stored in the shared memory segment. Actually, you can use redis and other caches... here's the shmop I use for not using redis and other nosqls.
    return array (
  1 => 
  array ('id' => '1','animation' => '13','skill_type' => '1','power_type' => '1','site' => '1','type' => '1','paramete' => '0','paramete2' => '0','paramete3' => '0','chance' => '0','ratio' => '1',
  ),
  2 => 
  array ('id' => '2','animation' => '3','skill_type' => '2','power_type' => '1','site' => '1','type' => '1','paramete' => '0','paramete2' => '0','paramete3' => '0','chance' => '0','ratio' => '2',
  ),..........................................

Конечно, вы должны учитывать, что если данные обновляются, то сегмент памяти также следует удалить и обновить данные…………… через shmop_delete можно удалить. Для этого вам потребуется самостоятельно рассмотреть заявку на проект.

Другое дело, что я здесь только для простого чтения, а сложного чтения и письма нет. В противном случае могут возникнуть неожиданные конфликты, такие как исключение процесса. Если сложные, то можно рассмотреть семафоры.~

Если вы сталкиваетесь со сценарием “ведущий-подчиненный” в проекте. См. эту статью по адресу http://tubaluer.iteye.com/blo…