English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
プロセス間の実行順序が決まっていないため、これは複雑なプロセススケジュールアルゴリズムに依存しています。したがって、複数のプロセスが同時に共有メモリにアクセスする可能性があり、予期せぬエラーが発生する可能性があります。シグナルの名前は奇妙なものですが、英語の意味を見ると非常に理解しやすいです。
semaphore 英[ˈseməfɔ:(r)] vt. 信号を出す,旗を振る;
指揮官のような役割です。
次の仮コードシグナルの使用を見てみましょう。
1、シグナルのユニーク識別子の作成
$ftok = ftok(__FILE__, 'a');
2、シグナルリソースIDの作成
$sem_resouce_id = sem_get($ftok);
3、シグナルの受信
sem_acqure($sem_resource_id);
4、シグナルの解放
sem_release($sem_resource_id);
5、シグナルの破棄
sem_remove($sem_resource_id);
不文雅な例を举いて、シグナルの生活での使用法を理解しやすくします。理解した後、プログラミングの分野に適用できます。
会社にはトイレが1つしかありません。トイレを使う際には、ロック(シグナル)を取得して、トイレが使用中であることを示します。以下のコードです:
sem_acqure($sem_resource_id);
従業員がトイレを使い終わったら、ロックを解除し、ロック(シグナル)を解放して、他の人が使用できることを示します。以下のコードです:
sem_release($sem_resource_id);
シンプルなロックを使うことで、現在のトイレ(共有メモリ)が使用可能かどうかを知ることができます。この例は不適切ですが、問題を説明するのに役立ちます。このブログも匂いがするブログですが、本当に大変でした。。。。以下にサンプルコードを示します:
<?php //共有メモリ領域の作成 $shm_key = ftok(__FILE__, 'a'); $shm_id = shm_attach($shm_key, 1024, 0755); //var_dump($shm_id);die(); resource(4) of type (sysvshm) const SHARE_KEY = 1; $child_list = []; //信号量の追加 $sem_id = ftok(__FILE__, 'b'); $signal = sem_get($sem_id); //$signal resource(5) of type (sysvsem) for ($i = 0; $i < 3; $i++) { $pid = pcntl_fork(); exit("Fork fail!".PHP_EOL); -1) { elseif ($pid == 0) { } //シグナルマネージャーを取得 sem_acquire($signal); if (shm_has_var($shm_id,SHARE_KEY)) { $count = shm_get_var($shm_id, SHARE_KEY); $count++; //ビジネス処理のシミュレーション $sec = rand(1, 3); sleep($sec); shm_put_var($shm_id, SHARE_KEY, $count); } $count = 0; $sec = rand(1, 3); sleep($sec); shm_put_var($shm_id, SHARE_KEY, $count); } echo "child process: ".getmypid()." is writing! now count is: $count ".PHP_EOL; //シグナルマネージャーを解放 sem_release($signal); exit("child process".getmypid()."end".PHP_EOL); } $child_list[] = $pid; } } while (count($child_list) > 0) { foreach ($child_list as $key => $pid) { $status = pcntl_waitpid($pid, $status); if ($status > 0 || $status == -1) { unset($child_list[$key]); } } sleep(1); } $count = shm_get_var($shm_id, SHARE_KEY); echo " $count ".PHP_EOL; //シグナルマネージャーを破壊 sem_remove($signal); shm_remove($shm_id); shm_detach($shm_id);