1

IDを持つオブジェクトがDBにあるかどうかをチェックし、ない場合はそのエントリを作成するPHPの操作があります。同じIDのリクエストが同時に発生する可能性があるため、IDが2回挿入されないようにします。

私は現在、次のコードを使用して、その特定のキーのDBへのアクセスをロック/ロック解除しています。

$semaphore = sem_get($keyForID, 1);

sem_acquire($semaphore);

// 1.) check for id
// 2.) insert object if it doesn't exist

sem_release($semaphore);

私の質問は次のとおりです。オブジェクトIDごとに個別のセマフォを作成しているので、これらのセマフォを明示的に削除するsem_remove必要がありますか、それともPHPは後で自動的に削除しsem_releaseますか?

セマフォを明示的に削除する必要がある場合、そのセマフォが現在別のスレッドによって取得されているかどうかを確認して、後者がクラッシュしないようにする簡単で信頼性の高い方法はありsem_releaseますか?共有メモリの使用が思い浮かびますが、スレッド数の読み取り/書き込みにはさらに別のセマフォが必要になります。

4

1 に答える 1

4

sem_remove特定のセマフォを明示的に破棄します。これにより、を使用して再作成されるまで、他の実行中のプロセスまたはスレッドの計算に使用できなくなりますsem_get。たとえば、3つのプロセスが同じセマフォにアクセスしようとして(同時アクセスが1つだけ)、最初のプロセスが他の2つのプロセスがセマフォを取得する前にそれを破棄した場合、後者の2つのプロセスは順番にではなく同時に実行される可能性があります(予想通り)。

sem_remove実行中の他のすべてのプロセスがそれを使用しなくなることがわかっている場合を除いて、実際には呼び出したくありません。

とにかく、あなたの状況では、同時アクセスをDB自体に依存することをお勧めします。DBにエントリを1つだけ作成する必要がある場合は、トランザクションを使用します。MySQLのMyISAMエンジンなどのトランザクションをサポートしていないDBを使用している場合は、トランザクションをサポートするエンジンに切り替えるか、MyISAMの特定のケースでは、アトミック操作を使用してみてください。

于 2012-11-26T09:16:04.980 に答える