ホームページ  >  記事  >  バックエンド開発  >  PHP 共有メモリの使用量と信号制御例の分析

PHP 共有メモリの使用量と信号制御例の分析

不言
不言オリジナル
2018-05-09 10:22:451137ブラウズ

この記事では主に PHP の共有メモリ使用量とシグナル制御の例を紹介します。必要な方はぜひ参考にしてください。コントロールの例。参考までに皆さんと共有してください。詳細は次のとおりです:

共有メモリ 共有メモリの使用は主に、同じマシン上の異なるプロセスで一部のデータを共有できるようにすることです。複数の php-fpm プロセス 現在のプロセスの使用状況。この種の通信は、プロセス間通信 (略して IPC) とも呼ばれます。

PHP の組み込み shmop 拡張機能 (Shared Memory Operations) は、共有メモリ操作のための一連の関数を提供します (おそらく、これを使用する人が少ないため、このドキュメントはまだ中国語に翻訳されていません)。 Linux では、これらの関数は shm* 一連の関数を呼び出すことによって直接実装されますが、Windows では、同じ呼び出しがシステム関数をカプセル化することによっても実装されます。

主な関数:

shmop_close

— 共有メモリブロックを閉じる

shmop_delete

— 共有メモリブロックを削除する

shmop_open

— 共有メモリブロックを作成または開く

shmop_ read

— 共有メモリブロックから読み取りdata

shmop_size

— 共有メモリブロックのサイズを取得します

shmop_write

— 共有メモリブロックにデータを書き込みます これに関連する非常に重要な関数もあります: ftok、ファイルの i ノード情報を使用します。 (*nix の stat または ls -i コマンドで表示) IPC 用に一意のキーを作成します (ファイル/フォルダーの i ノードは一意です)。この関数は、同じ名前のシステム関数を直接呼び出すことによって Linux でも実装されますが、Windows では依然として一部のカプセル化が使用されています。

簡単なカウントの例:

<?php
# 创建一块共享内存
$shm_key = ftok(__FILE__, &#39;t&#39;);
$shm_id = shmop_open($shm_key, &#39;c&#39;, 0644, 8);
# 读取并写入数据
$count = (int) shmop_read($shm_id, 0, 8) + 1;
shmop_write($shm_id, str_pad($count, 8, &#39;0&#39;, STR_PAD_LEFT), 0);
// echo shmop_read($shm_id, 0, 8);
# 关闭内存块,并不会删除共享内存,只是清除 PHP 的资源
shmop_close($shm_id);

上記のコードは count + 1 を実行せず、データは異なるプロセス間で共有されます。つまり、このメモリを手動で削除しない限り、このデータはリセットされません。

少し注意が必要な点があります。shmop_open の 2 番目のパラメータは fopen の 2 番目のパラメータと同様にフラグであり、その値は次のとおりです。

"a" 読み取り専用アクセス。

"c" if メモリセグメントが存在しない場合は、メモリセグメントを作成します。存在する場合は、読み取りと書き込みが可能です。

"n" は、新しいメモリセグメントを作成します。キーがすでに存在する場合、作成は失敗します。これは、共有メモリの安全な使用を考慮するためです。

また、使用される共有メモリセグメントは固定長であるため、保存時と読み込み時にデータの長さを計算する必要があり、そうしないと書き込みに失敗したり、null値が読み込まれる可能性があります。

信号制御

上記のデータの保存には共有メモリが使用されるため、複数のプロセスが同時に共有メモリにデータを書き込んでいるかどうか、競合を回避する必要があるかどうかを考慮する必要があります。その場合は、制御用のセマフォを導入する必要があります。 PHP も同様の組み込み拡張機能 sysvsem を提供しています (この拡張機能は Windows 環境では使用できません。ドキュメントでは ftok 関数もこの拡張機能に含まれていますが、実際には ftok は標準関数ライブラリで提供されているため、 Windows でも使用可能です)。

セマフォ制御について話す前に、別の興味深いことについて話させてください。公式ドキュメントを見ると、共有メモリ操作 (shm_*) 用の関数もあることがわかります。これは、これらは実際には同じカテゴリ (または、同じ作成者) )、1 つは sysvmsg (キュー メッセージ) です。関数の実装は若干異なりますが、実際に行うことは基本的に同じです。これと上記の shmop 拡張機能の違いは何ですか? shmop ソース コードの下の README ファイルには簡単な説明があります:

PHP には、Christian Cartus 32982644a4ae8a6ce575374773bddd52 によって書かれた共有メモリ拡張機能 (sysvshm) がすでにありましたが、残念ながら、この拡張機能は PHP のみを念頭に置いて設計されており、私たちが念頭に置いていた基本的な SHM にとっては非常に面倒な高レベルの機能を提供します。

簡単に言うと、sysvshm 拡張機能によって提供されるメソッドは、ユーザーのデータをそのまま保存するのではなく、最初に PHP の変数シリアル化関数を使用して処理することです。パラメータはシリアル化されて保存されます。これは、これらの方法で保存されたデータを PHP 以外のプロセスと共有できないことを意味します。ただし、上記の拡張機能では、shmop_write は文字列のみを書き込むことができます。では、なぜ sysvshm は Windows もサポートしないのでしょうか? shm* 系の関数をカプセル化した tsrm_win32.h のヘッダー ファイルを導入していないためです。

シグナル制御導入後の例:

<?php
$id_key = ftok(__FILE__, &#39;t&#39;);
$sem_id = sem_get($id_key);
# 请求信号控制权
if (sem_acquire($sem_id)) {
  $shm_id = shmop_open($id_key, &#39;c&#39;, 0644, 8);
  # 读取并写入数据
  $count = (int) shmop_read($shm_id, 0, 8) + 1;
  shmop_write($shm_id, str_pad($count, 8, &#39;0&#39;, STR_PAD_LEFT), 0);
  // echo shmop_read($shm_id, 0, 8);
  # 关闭内存块
  shmop_close($shm_id);
  # 释放信号
  sem_release($sem_id);
}

しかし、書き込み競合をローカルでシミュレートすることは実際には非常に困難です(コンピューターの実行速度を考慮すると)。ローカルテストで、for ループ操作を使用するときに shmop_close を使用してリソースを閉じないと、共有メモリをオープンできないことを警告するエラーが表示されます。これは、共有メモリが前の操作によって占有されており、まだ解放されていないことが原因である可能性があります。

関連する推奨事項:

shmop シリーズ関数は PHP 共有メモリ実装メソッドを使用します

PHP 共有メモリで使用されるコードの詳細な紹介


以上がPHP 共有メモリの使用量と信号制御例の分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。