Heim  >  Artikel  >  Backend-Entwicklung  >  PHP verwendet einfach die Shmop-Funktion, um gemeinsam genutzten Speicher zu erstellen und so die Serverlast zu reduzieren

PHP verwendet einfach die Shmop-Funktion, um gemeinsam genutzten Speicher zu erstellen und so die Serverlast zu reduzieren

不言
不言Original
2018-07-06 15:57:193204Durchsuche

Dieser Artikel stellt hauptsächlich vor, wie PHP die Shmop-Funktion verwendet, um gemeinsam genutzten Speicher zu erstellen, um die Serverlast zu reduzieren. Jetzt kann ich ihn mit Ihnen teilen

Im vorherigen Artikel dieses Blogs [Verstehen Sie das Konzept, die Vor- und Nachteile von Shared Memory] wurde das Konzept des Shared Memory bereits erläutert. Lassen Sie uns einfach gemeinsam genutzten Speicher verwenden (tatsächlich können Sie auch andere Tools wie Redis verwenden).

PHP verfügt über zwei Schnittstellensätze für die Speicherfreigabe. Eine davon ist shm, bei dem es sich tatsächlich um eine gemeinsame Nutzung von Variablen handelt und die Objektvariablen vor dem Speichern serialisiert. Die Verwendung ist recht praktisch, aber serialisierter Speicher ist für Speicherzugriffsvorgänge, bei denen die Effizienz im Vordergrund steht, bedeutungslos. Die andere Funktion ist shmop, die bei Linux und Windows üblich ist, deren Funktion jedoch schwächer ist als bei shm. Unter Linux werden diese Funktionen direkt durch den Aufruf der shm*-Funktionsreihe implementiert, während sie unter Windows auch durch das Kapselungssystem implementiert werden Funktionen haben den gleichen Aufruf getätigt. Was ich hier zuerst verwende, ist Shmop.

Um ein Shared-Memory-Segment zu erstellen, müssen Sie die Funktion shmop verwenden und dann die Erweiterung aktivieren. Weitere Informationen finden Sie unter [Shmop-Erweiterung für PHP aktivieren, um Shared Memory zu implementieren].

Die Hauptfunktion von shmop

shmop_open (einen gemeinsam genutzten Speicherblock erstellen oder öffnen), shmop_write (Daten in einen gemeinsam genutzten Speicherblock schreiben), shmop_read (Daten aus einem gemeinsam genutzten Speicherblock lesen) , shmop_size (Größe eines gemeinsam genutzten Speicherblocks ermitteln), shmop_close (gemeinsam genutzten Speicherblock schließen), shmop_delete (gemeinsam genutzten Speicherblock löschen)

<?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);

shmop_open (Speichersegment erstellen)

Das erste, was in dieser Funktion erscheint, ist der System-ID-Parameter. Dies ist eine Nummer, die das gemeinsam genutzte Speichersegment im System identifiziert. Der zweite Parameter ist der Zugriffsmodus, der dem Zugriffsmodus der fopen-Funktion sehr ähnlich ist. Sie können in 4 verschiedenen Modi auf ein Speichersegment zugreifen:

Modus „a“, der Ihnen den Zugriff auf schreibgeschützte Speichersegmente ermöglicht, schreibgeschützten Zugriff
Modus „w“, der Ihnen den Zugriff ermöglicht Nur-Lese-Speichersegmente Speichersegment zum Lesen und Schreiben, Lese- und Schreibmodus
„c“, es wird ein neues Speichersegment erstellt, oder wenn das Speichersegment bereits vorhanden ist, versuchen Sie, es zum Lesen und Schreiben zu öffnen
Modus „n“, es wird ein neuer Speicher erstellt. Wenn das Segment mit demselben Schlüssel bereits vorhanden ist, schlägt die Erstellung fehl. Dies dient der sicheren Nutzung des gemeinsam genutzten Speichers.
Der dritte Parameter ist die Erlaubnis des Speichersegments. Sie müssen hier einen Oktalwert angeben.

Der vierte Parameter gibt die Speichersegmentgröße in Bytes an. Da das verwendete Shared-Memory-Segment eine feste Länge hat, muss beim Speichern und Lesen die Länge der Daten berechnet werden, da sonst der Schreibvorgang fehlschlagen oder ein Nullwert gelesen werden kann. .

Beachten Sie, dass diese Funktion eine ID-Nummer zurückgibt, die von anderen Funktionen verwendet werden kann, um dieses gemeinsam genutzte Speichersegment zu bearbeiten. Diese ID ist die Shared-Memory-Zugriffs-ID, im Gegensatz zur System-ID, die als Parameter übergeben wird. Achten Sie darauf, die beiden nicht zu verwechseln. Bei einem Fehler gibt shmop_open FALSE zurück. Beim Erstellen eines Speicherblocks wird empfohlen, für den Schlüsselparameter Konstanten anstelle von Variablen zu verwenden, da es sonst wahrscheinlich zu Speicherverlusten kommt.

shmop_write (Daten in das Speichersegment schreiben)

Diese Funktion ähnelt der fwrite-Funktion, die zwei Parameter hat: die Open-Stream-Ressource (zurückgegeben von fopen) und die Daten, die Sie schreiben möchten. Auch die Funktion shmop_write übernimmt diese Aufgabe.

Der erste Parameter ist die von shmop_open zurückgegebene ID, die den gemeinsam genutzten Speicherblock identifiziert, den Sie bearbeiten. Der zweite Parameter sind die Daten, die Sie speichern möchten, und der letzte dritte Parameter ist die Position, an der Sie mit dem Schreiben beginnen möchten. Standardmäßig verwenden wir immer 0, um anzugeben, wo mit dem Schreiben begonnen werden soll. Beachten Sie, dass diese Funktion bei einem Fehler FALSE und bei Erfolg die Anzahl der geschriebenen Bytes zurückgibt.

shmop_read (Daten aus dem Speichersegment lesen)

Das Lesen von Daten aus dem gemeinsam genutzten Speichersegment ist einfach. Sie benötigen lediglich ein offenes Speichersegment und die Funktion shmop_read. Diese Funktion akzeptiert einige Parameter und funktioniert wie fread.

Bitte achten Sie hier auf die Parameter. Die Funktion shmop_read akzeptiert die von shmop_open zurückgegebene ID, die wir bereits kennen, akzeptiert aber auch zwei weitere Parameter. Der zweite Parameter ist die Position im Speichersegment, aus der Sie lesen möchten, und der dritte Parameter ist die Anzahl der Bytes, die Sie lesen möchten. Der zweite Parameter kann immer 0 sein und den Anfang der Daten angeben, aber der dritte Parameter kann problematisch sein, da wir nicht wissen, wie viele Bytes wir lesen möchten.

Dies ist sehr ähnlich zu dem, was wir in der fread-Funktion tun, die zwei Parameter akzeptiert: die offene Stream-Ressource (zurückgegeben von fopen) und die Anzahl der Bytes, die Sie aus dem Stream lesen möchten. Verwenden Sie die Dateigrößenfunktion (die die Anzahl der Bytes in einer Datei zurückgibt), um sie vollständig zu lesen.

shmop_size (gibt die tatsächliche Größe der Speichersegmentdaten zurück)

Zum Beispiel haben wir einen Speicherplatz mit einer Länge von 100 Bytes geöffnet, aber die tatsächliche Länge der gespeicherten Daten nur 90 beträgt, beträgt der durch die Verwendung von shmop_size zurückgegebene Wert 90.

shmop_delete (Speichersegment löschen)

该函数仅接受一个参数:我们希望删除的共享内存 ID,这不会实际删除该内存段。它将该内存段标记为删除,因为共享内存段在有其他进程正在使用它时无法被删除。shmop_delete 函数将该内存段标记为删除,阻止任何其他进程打开它。要删除它,我们需要关闭该内存段。在创建内存块时建议key参数用常量而不用变量,否则很有可能造成内存泄露。

shmop_close(关闭内存段)

我们在对内存段进行读取和写入,但完成操作后,我们必须从它解除,这非常类似于处理文件时的 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

命令说明

key :共享内存的唯一的key值,共享内存通过该key来判断你读取的是哪一块内存。
shmid:当使用key来获取内存时,你获得的是这个id的值。它作为你操作内存块的标识。
owner:创建该共享内存块的用户
perms:该共享内存的读写权限,8禁止,可以是777,与文件的读写权限一致。
bytes:该内存块的大小
nattch:连接该内存块的进程数
status:当前状态,如:dest,即将删除等。

项目实际应用小案例

<?php
/**
 * 将领技能
 */
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 (
  1 => 
  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;,
  ),
  2 => 
  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;,
  ),..........................................

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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

php操作共享内存shmop类及简单使用测试的代码

php实现共享内存进程通信函数(_shm)

Das obige ist der detaillierte Inhalt vonPHP verwendet einfach die Shmop-Funktion, um gemeinsam genutzten Speicher zu erstellen und so die Serverlast zu reduzieren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn