Exemple détaillé de la façon dont PHP crée de la mémoire partagée pour réduire la charge

藏色散人
Libérer: 2023-04-11 08:30:02
avant
3976 Les gens l'ont consulté

Cet article vous présentera comment créer de la mémoire partagée en PHP pour réduire la charge. Ici, vous devez comprendre une fonction shmop. Suivons l'article pour apprendre ~

PHP dispose de deux ensembles d'interfaces pour le partage de mémoire. L'un est shm, qui est en fait un partage de variables et sérialisera les variables d'objet avant de les stocker. Il est assez pratique à utiliser, mais le stockage sérialisé n'a aucun sens pour les opérations d'accès à la mémoire qui privilégient l'efficacité. L'autre est shmop, qui est commun à Linux et Windows, mais sa fonction est plus faible que shm Sous Linux, ces fonctions sont directement implémentées en appelant la série de fonctions shm*, tandis que sous Winodows, elles sont également implémentées par le système d'encapsulation. fonctions. a fait le même appel.

Pour créer un segment de mémoire partagée, vous devez utiliser la fonction shmop, le prérequis est donc d'activer l'extension. [Apprentissage recommandé : Tutoriel vidéo PHP]

Fonctions principales de shmop

shmop_open (créer ou ouvrir un bloc de mémoire partagée), shmop_write (écrire des données dans un bloc de mémoire partagée), shmop_read (lire à partir d'un bloc de mémoire partagée) data), shmop_size (obtenir la taille du bloc de mémoire partagée), shmop_close (fermer le bloc de mémoire partagée), shmop_delete (supprimer le bloc de mémoire partagée)

<?php
//创建一块共享内存
$shm_key = 0x4337b101;
$shm_id = @shmop_open($shm_key, &#39;c&#39;, 0644, 1024);
//读取并写入数据
$data = shmop_read($shm_id, 0, 1024);
shmop_write($shm_id, json_encode($data), 0);
$size = shmop_size($shm_id); //获取内存中实际数据占用大小
//关闭内存块,并不会删除共享内存,只是清除 PHP 的资源
shmop_close($shm_id);
Copier après la connexion

shmop_open (créer un segment de mémoire)

La première chose qui apparaît dans cette fonction est le paramètre ID système. Il s'agit d'un numéro qui identifie le segment de mémoire partagée dans le système. Le deuxième paramètre est le mode d'accès, qui est très similaire au mode d'accès de la fonction fopen. Vous pouvez accéder à un segment mémoire selon 4 modes différents :

Mode "a", qui permet d'accéder à un segment mémoire en lecture seule, mode d'accès en lecture seule "c", qui crée un nouveau segment mémoire, ou si la mémoire segment Existe déjà, essayez de l'ouvrir en lecture et en écriture
Mode "n", il crée un nouveau segment de mémoire Si la même clé existe déjà, la création échouera pour une utilisation sûre de la mémoire partagée.

Le troisième paramètre concerne les autorisations du segment de mémoire. Vous devez fournir une valeur octale ici.

Le quatrième paramètre fournit la taille du segment de mémoire en octets. Étant donné que le segment de mémoire partagée utilisé est de longueur fixe, la longueur des données doit être calculée lors du stockage et de la lecture, sinon l'écriture risque d'échouer ou une valeur nulle peut être lue. .

Veuillez noter que cette fonction renvoie un numéro d'identification qui peut être utilisé par d'autres fonctions pour opérer sur ce segment de mémoire partagée. Cet ID est l'ID d'accès à la mémoire partagée, contrairement à l'ID système, qui est passé en paramètre. Attention à ne pas confondre les deux. En cas d'échec, shmop_open retournera FALSE. Lors de la création d'un bloc mémoire, il est recommandé d'utiliser des constantes au lieu de variables pour le paramètre clé, sinon cela risque de provoquer des fuites de mémoire.

shmop_write(écrire des données dans un segment de mémoire)

Cette fonction est similaire à la fonction fwrite, qui prend deux paramètres : la ressource de flux ouvert (renvoyée par fopen) et les données que vous souhaitez écrire. La fonction shmop_write effectue également cette tâche.

Le premier paramètre est l'ID renvoyé par shmop_open, qui identifie le bloc de mémoire partagée sur lequel vous opérez. Le deuxième paramètre correspond aux données que vous souhaitez stocker et le troisième paramètre final est la position où vous souhaitez commencer l'écriture. Par défaut, nous utilisons toujours 0 pour indiquer par où commencer l'écriture. Notez que cette fonction renvoie FALSE en cas d'échec et le nombre d'octets écrits en cas de succès.

shmop_read (lire les données du segment de mémoire)

La lecture des données du segment de mémoire partagée est très simple. Tout ce dont vous avez besoin est un segment de mémoire ouvert et la fonction shmop_read. Cette fonction accepte certains paramètres et fonctionne comme fread.

Veuillez faire attention aux paramètres ici. La fonction shmop_read acceptera l'ID renvoyé par shmop_open, que nous connaissons déjà, mais elle acceptera également deux autres paramètres. Le deuxième paramètre est l'emplacement dans le segment de mémoire à partir duquel vous souhaitez lire, et le troisième est le nombre d'octets que vous souhaitez lire. Le deuxième paramètre peut toujours être 0, indiquant le début des données, mais le troisième paramètre peut être problématique car nous ne savons pas combien d'octets nous voulons lire.

C'est très similaire à ce que nous faisons dans la fonction fread, qui prend deux paramètres : la ressource du flux ouvert (renvoyée par fopen) et le nombre d'octets que vous souhaitez lire dans le flux. Utilisez la fonction filesize (qui renvoie le nombre d'octets dans un fichier) pour le lire complètement.

shmop_size (renvoie la taille réelle des données du segment de mémoire)

Par exemple, si nous ouvrons un espace mémoire d'une longueur de 100 octets, mais que la longueur réelle des données stockées n'est que de 90, alors la valeur renvoyée en utilisant shmop_size est 90.

shmop_delete (Supprimer le segment de mémoire)

Cette fonction n'accepte qu'un seul paramètre : l'ID de mémoire partagée que nous souhaitons supprimer, cela ne supprimera pas réellement le segment de mémoire. Il marque le segment de mémoire pour suppression car un segment de mémoire partagée ne peut pas être supprimé pendant qu'un autre processus l'utilise. La fonction shmop_delete marque le segment de mémoire pour suppression, empêchant tout autre processus de l'ouvrir. Pour le supprimer, nous devons fermer ce segment de mémoire. Lors de la création d'un bloc mémoire, il est recommandé d'utiliser des constantes au lieu de variables pour le paramètre clé, sinon cela risque de provoquer des fuites de mémoire.

shmop_close (fermer le segment de mémoire)

我们在对内存段进行读取和写入,但完成操作后,我们必须从它解除,这非常类似于处理文件时的 fclose 函数。打开包含一个文件的流并在其中读取或写入数据后,我们必须关闭它,否则将发生锁定。

简单测试结果查看

我是在LNMP环境下操作的,如果你也和我一样,在执行完简单的操作之后,可以使用linux命令查看一下地址和占用大小

# ipcs -m
[root@bogon ~]# 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
Copier après la connexion

命令说明

key :共享内存的唯一的key值,共享内存通过该key来判断你读取的是哪一块内存。 owner:创建该共享内存块的用户 bytes:该内存块的大小 status:当前状态,如:dest,即将删除等。

项目实际应用小案例

/**
 * 将领技能
 */
class Generalskill_model extends CI_Model {<!-- -->

 private $_memory_key = 0x4337b001; //共享内存地址key
 private $_memory_size = 1048576;  //开辟共享内存大小 //最好根据实际数据长度大小定义。

 public function __construct() {<!-- -->
 parent::__construct();
 }

 public function get_skill_list() {<!-- -->
 $data = [];
 $shmid = @shmop_open($this->_memory_key, &#39;a&#39;, 0644, $this->_memory_size); 

 if ($shmid === FALSE) {<!-- -->
  $shmid = @shmop_open($this->_memory_key, &#39;c&#39;, 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(&#39;/[\x00-\x1F\x80-\x9F]/u&#39;, &#39;&#39;, trim(shmop_read($shmid, 0, $this->_memory_size))), true);
 @shmop_close($shmid);
 return $data; 

 }

 public function return_skill_list() {<!-- --> //这里是一个超大的数组,其实就是把这个数组json化,然后存入共享内存段。 其实可以用redis等其他缓存...这里我就是为了不用redis等其他nosql才用的shmop
 return array (
=> 
 array (&#39;id&#39; => &#39;1&#39;,&#39;animation&#39; => &#39;13&#39;,&#39;skill_type&#39; => &#39;1&#39;,&#39;power_type&#39; => &#39;1&#39;,&#39;site&#39; => &#39;1&#39;,&#39;type&#39; => &#39;1&#39;,&#39;paramete&#39; => &#39;0&#39;,&#39;paramete2&#39; => &#39;0&#39;,&#39;paramete3&#39; => &#39;0&#39;,&#39;chance&#39; => &#39;0&#39;,&#39;ratio&#39; => &#39;1&#39;,
 ),
=> 
 array (&#39;id&#39; => &#39;2&#39;,&#39;animation&#39; => &#39;3&#39;,&#39;skill_type&#39; => &#39;2&#39;,&#39;power_type&#39; => &#39;1&#39;,&#39;site&#39; => &#39;1&#39;,&#39;type&#39; => &#39;1&#39;,&#39;paramete&#39; => &#39;0&#39;,&#39;paramete2&#39; => &#39;0&#39;,&#39;paramete3&#39; => &#39;0&#39;,&#39;chance&#39; => &#39;0&#39;,&#39;ratio&#39; => &#39;2&#39;,
 ),..........................................
Copier après la connexion

当然你要考虑的是,如果数据更新的话,那么内存段也要删除,并且更新数据…通过shmop_delete可以删除 。这就需要你们自己根据项目应用来考虑了

还有就是这篇文章只是为了简单的读,并没有出现复杂的读写,否则可能会出现进程互斥等意想不到的冲突如果复杂,那么就可以考虑信号量了。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:jb51.net
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal