ネットで調べると2つの方法がありますが、どちらもあまり良い方法ではありません。1つは単純にプロセスID + タイムスタンプ、またはプロセスID + 乱数を使用して近似的な一意のIDを生成する方法です。簡単ですが、私はそうではありません。これは「完璧」を追求する意欲があり、さらに、このプロセスは Apache2 以降も長期間続くため、生成された ID の衝突の可能性は依然として比較的高いです。2 番目のアイデアは、Mysql の自動インクリメント フィールドを使用することです。効率が低いことは言うまでもなく、私の設計にはデータベースがまったくありません。
増分 ID の取得は次のプロセスです:
1. 特定のグローバル ストレージから ID を読み取ります
2. ID に 1 を加算します
3. マルチプロセスまたはスレッド プログラムで、ID をグローバル ストレージに格納します。上記の 3 つのステップを追加する必要があります。ステップがシングルステップのアトミック操作である場合にのみ、ID を一意にすることができます。
これは、ほとんどの Java プログラムがマルチスレッド モードで実行され、各スレッドが Java プロセスで変数を共有でき、スレッド操作の同期を制御するためにスレッド ロックを簡単に追加できるため、これは簡単に解決できます。 PHP では、グローバル ID をセッション内に、または最悪の場合はファイル内に保存することは問題ありませんが、プロセス間の同期が問題になります。
実際、プロセスのスケジューリングと管理はオペレーティング システムのカーネルが実装する必要がある機能です。今回紹介するセマフォ (セマフォとも呼ばれます) は、Unix/Linux 上のプロセスの同期を解決するテクノロジーです。
信号機はもともと鉄道の管理機構として使用されていましたが、現在私たちが目にするほとんどの鉄道は複線ですが、一部の区間は山や地形の影響を受け、1つの列車のみが使用できるようにする必要があります。これらのセクションを同時に実行します。初期の鉄道は信号機によって管理されており、列車が通過しないときは信号機が停止し、列車が通過するときに信号機が使用されるようになりました。列車が出発する場合、出口信号機が空になった場合にのみ、この区間に入ることができます。別の列車が入線すると、信号機は再び混雑します...鉄道の安全でスムーズな運行を確保します。
鉄道行政がセマフォを制御するのと同じように、Unix システムはセマフォのステータスを管理および制御します。したがって、セマフォはカーネルによって管理されるだけでなく、プロセス間の同期も制御できます。スレッド間の同期。
セマフォはシステムプロセス間通信技術 (IPC) に属します。今日は PHP の観点からセマフォの使用法のみを紹介します。IPC の技術的な詳細については、Stevens の権威ある書籍「UNIX Network Programming Volume 2 Inter-Process」を参照してください。コミュニケーション"。
最初に最終的なコードを見てください:
// ----------------- ------ -----------------------------
// シリアル番号IDをインクリメント(1~1000000000)
/ /
// ID は共有メモリに保存され、セマフォを通じて同期されます
// ----------------------------- --- ------------------
$IPC_KEY = 0x1234; //System V IPC KEY
$SEQ_KEY = "SEQ";共有メモリ内
//「1234」を KEY として使用して既存のセマフォを作成または取得します
$sem_id = sem_get($IPC_KEY);
//「1234」を KEY として使用して既存の共有メモリを作成または関連付けます
$shm_id = shm_attach($IPC_KEY, 64);
//ロックに相当するセマフォを占有します。
sem_acquire($sem_id);
// 共有メモリからシーケンス番号を取得します。 ID
$id = @shm_get_var($shm_id, $SEQ_KEY);
if ($id == NULL || $id >= 1000000000)
{
$id = 1;
else
{
$id++;
}
//「++」以降の ID を共有メモリに書き込みます
shm_put_var($shm_id, $SEQ_KEY, $id);
//ロックを解除するのと同じです
sem_release($sem_id); // 共有メモリの関連付けを閉じる
shm_detach($shm_id)
echo "シリアル ID:{$id}";
行 009 は 16 進整数 KEY を定義します。PHP では、System V の IPC メカニズムのみがサポートされており、KEY を介して指定されたリソース (メッセージ キュー、セマフォ、共有メモリ) に関連付けられる必要があります。行
010 は、増分 ID を共有メモリに保存する KEY を定義しています。これは、PHP による System V 共有メモリのアイドル使用です。変数は、ハッシュテーブルと同様の KEY-VALUE メソッドに保存する必要があります。上記のコードでは、共有メモリは ID のストレージ コンテナとして使用されています。これは、セッションやファイルなどの他のメカニズムで置き換えることもできます。この記事では、共有メモリについての知識を後で説明します。前に勧めた本を忘れないでください)。
013行目、1234をキーとするセマフォをシステム内で取得し、システム内に存在しない場合は作成します。
行 015 は、行 13 と同様に、1234 をキーとしてシステム内に共有メモリを取得します。2 番目のパラメータ 64 は、64 バイト サイズの共有メモリを作成することを意味します。
018 行目から 034 行目、同期コード領域。プロセスまたはスレッドが sem_acquire 関数を実行してセマフォを占有すると、sem_release 関数を呼び出してセマフォを解放するまで、他のプロセスまたはスレッドは sem_acquire の実行時にブロックされます。行 021 では、共有メモリから ID を取得します。関数 shm_get_var には、エラー メッセージを隠すために「@」が付加されています (初めて実行するときは、共有メモリに KEY として「SEQ」を持つデータは存在しません)。警告メッセージがページに印刷されます)。
他の文は非常に簡単なので説明する必要はありません。
プログラムがコンパイルされた後、この PHP ページにアクセスすると、数値が段階的に出力されます。
システム コマンド ipcs を使用して、プログラムで作成されたセマフォと共有メモリを表示できます。
$ ipcs
------ 共有メモリ セグメント --------
key shmid owner perms bytes natch status
0x00001234 1212443 www-data 666 64 0
------ セマフォ配列 --------
key semid owner perms nsems
0x00001234 163841 www-data 666 3
------ メッセージキュー -------- - ----
key msqid owner perms used-bytesmessages
最初の 2 つの段落は共有メモリとセマフォであり、0x00001234 は作成した KEY です。
コマンド ipcrm を使用して削除することもできます:
$ ipcrm -M 0x00001234 #共有メモリの削除
$ ipcrm -S 0x00001234 #セマフォの削除
-------- -- ------------------------
PHP マニュアルには IPC に関する情報がほとんどありません。Stevens がすでにそれを行っていることは想像に難くありません。これについては 10 年以上前に言及しましたが、これは PHP にパッケージ化されたばかりなので、さらに詳しい説明が必要でしょうか?
このテキストでは、ID によるセマフォの使用についてのみ説明しています。自動インクリメント ID を生成する簡単な方法がある場合は、お知らせください。
セマフォの実行効率を知りたいという友人もいるかもしれません。古い流行語で要約しましょう。「非常に速い」です。
http://www.bkjia.com/PHPjc/320685.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/320685.html技術記事ネットで調べると2つの方法がありますが、どちらもあまり良い方法ではありません。1つは単純にプロセスID + タイムスタンプ、またはプロセスID + 乱数を使用して近似的な一意のIDを生成する方法です。簡単ではありますが、そうではありません。 「完璧」を追求する人に最適です...