単台サーバのPHPプロセス間で共有メモリを実現する方法


開発者がphpプロセスを共有メモリの読み書きを実現するには、まずIPC関数、すなわちphpコンパイルインストール時に指定します。--enaber-shmop  と--enabole-sysvsemの2つのオプションがあります。
IPC(Inter-process communication)はUnix標準機構であり、同じホストと異なるプロセスの間で互いに可能にする方法を提供している。基本的なIPC処理機構は、メモリ、信号量、およびメッセージキューを共有する3つの種類がある。本論文では主に共有メモリと信号量の使用について議論する。異なる処理プロセスの間で共有メモリを使用することは、異なるプロセス間の相互作用を実現するための良い方法である。プロセスで共有されているメモリにメッセージを書き込むと、他のすべてのプロセスにも書き込みが見られます。とても便利です。PHPには共有メモリの助けがあります。同じPHPスクリプトを実行している間に異なる結果を返すことができます。PHP同時運転数量のリアルタイム照会などを実現する。
共有メモリは、2つ以上のプロセスが所与の記憶領域を共有することを可能にする。データはクライアントとサーバの間でコピーする必要がないので、これが一番早いIPCです。共有メモリを使用する唯一の方法は、複数のプロセスが所与の記憶領域に同期アクセスすることである。
共有メモリセグメントはどうやって作りますか?下のコードは共有メモリを作成してくれます。
$shm_id = shmop_open($key, $mode, $perm, $size);
注意してください。共有メモリセグメントごとに一意のIDがあります。PHPではshmop_オープンは共有メモリセグメントのIDを返します。ここで私たちは$shm_を使います。これはIDです。keyは共有メモリセグメントのKey値を論理的に表しています。異なるプロセスは同じキーを選択するだけで、同じセグメントの記憶を共有することができます。私たちは一つの列(ファイル名のようなもの)のハッシュ値をkey_id.$modeとして共有メモリの使い方を指定しています。ここは新築ですので、値は'c'Cがcreateを取るという意味です。共有メモリが既に確立されているならば、'a'を使ってaccessの意味を取ってください。permパラメータが定義した権限は、8進数で、権限定義についてはUNIXファイルシステムを参照してください。sizeは共有メモリのサイズを定義しています。ちょっとfopenのようですが、ファイルと同じように扱わないでください。後の説明はこの点が見えます。
たとえば:
$shm_id = shmop_open(0xff3, "c", 0644, 100);
ここで共有メモリセグメントキーの値0 xf 3 Crw-r-rを開きました。サイズは100バイトです。
既存の共有メモリが必要な場合は、shmop_を呼び出してください。openでは3つ目、4つ目のパラメータを0とします。
Unixでは、システム全体のIPCリソース状態をコマンドラインでipcsで照会することができます。しかし、一部のシステムはスーパーユーザーが実行できるように要求しています。下図はipcsの運転結果です。
上の図には4つの共有メモリセグメントが表示されています。このうち4番目のキーは0 x 0000 ff 3であり、私たちが実行したPHPプログラムが作成したものです。ipcsの使い方については、UNIXユーザーズマニュアルを参照してください。
共有メモリはどうやって解放しますか?
共有メモリをリリースする方法はPHP指令を呼び出すことです。shmop_。delete($id)
shmop_delete($id);
ドルidはあなたがshmop_を呼び出します。openが持っているshmop_opの戻り値。もう一つの方法はUNIXの管理命令を使うことです。
ipcrm id、idはあなたがipcsで見たIDです。あなたのプログラムの中のドルIDと違います。ただし、共有メモリのセグメントをipcrmで直接削除すると、他の未知のプロセスにつながる可能性がありますので、この重複した共有メモリを引用すると予測できないエラーが発生します。
どうやってメモリを共有しますか?
下記の関数を使って共有メモリにデータを書き込みます。
int shmop_write (int shmid, string data, int offset)
中にshmidはshmop_を使っています。openはハンドルを返します。Data変数は保存するデータを保存します。offsetは、共有メモリの最初のバイトの書き込み位置(0で開始)を説明する。
読み込み操作は:
string shmop_read (int shmid, int start, int count)
同様に、$shmidを指定して、開始オフセット量(0で開始)、総読み込み数。結果列を返します。このように、共有メモリセグメントをバイト配列として扱うことができます。いくつか読んでからいくつか書いてください。何をしたいですか?とても便利です。
今は、別のPHPプロセスで読み書き、作成、共有メモリの削除を行いますが、大丈夫です。しかし、実際に実行しているのはPHPプロセスだけではないことは明らかです。複数のプロセスの場合、まだ個々のプロセスの処理方法を踏襲していると、問題に直面します。有名な並行と相互反発の問題です。例えば、2つのプロセスが同時に同じメモリを読み書きする必要があります。二つのプロセスが同時に書込み操作を実行すると、最後に実行されたプロセスの内容であり、さらに2つのプロセスによって書き込まれたデータが順番にランダムに出現する一部分が混在しているというエラーのデータが得られます。これは明らかに受け入れられない。この問題を解決するためには,相互反発機構を導入しなければならない。相互反発メカニズムは多くのオペレーティングシステムの教材で専門的に説明されています。ここではあまり繰り返しません。相互反発メカニズムを実現する一番簡単な方法は信号を使うことです。信号量は、他のIPC機関(パイプライン、FIFO、メッセージキュー)とは異なる別のプロセス間(IPC)の方法である。これはマルチプロセスの共有データの保存を制御するための記録器です。同様に、ipcsとipcrmで信号灯の使用状態に関するクエリと削除操作ができます。PHPでは次の関数で新たな信号量を作成し、信号量のハンドルを返します。このkeyが指す信号量が既に存在すれば、sem_getは直接に信号量のハンドルを操作する。
int sem_get(int key [, int max_acquire [, int perm]])
$max_acquireは、信号が解放されるのを待つことなく、最大数のプロセスで信号に入ることができることを指定しています。permは権限を指定しています。
もしあなたが成功したら、信号量を持っています。あなたがそれにできるのは2つだけです。要求、リリース。リリース操作を実行すると、システムは信号の値を一つ減らします。0より小さいなら0にします。要求動作を実行すると、システムはこの信号値を追加します。設定された最大値より大きい場合、他のプロセスが最大値より小さいまで処理を保留します。一般的には最大値を1に設定します。これにより、プロセスが要求された場合、他の後のプロセスは、相互反発エリアから退出した後に信号量を解放して、相互反発エリアに入ることができ、同時に独占方式に設定されます。このような信号量は、しばしば二重信号量と呼ばれる。もちろん、初値が任意の正数であれば、共有リソース単位がどれぐらいあるかを示しています。