2012-11-25 2 views
1

ID가있는 객체가 DB에 있는지 검사하고 그렇지 않은 경우 항목을 작성하는 PHP 작업이 있습니다. 동일한 ID에 대한 요청이 동시에 발생할 수 있으므로 ID가 두 번 삽입되는 것을 방지하고 싶습니다. 나는 모든 객체 ID에 대한 개별 세마포어를 만드는거야 때문에 :PHP에서 마지막 sem_release 후 Semaphore 제거하기

$semaphore = sem_get($keyForID, 1); 

sem_acquire($semaphore); 

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

sem_release($semaphore); 

내 질문은 : 나는 현재 특정 키에 대한 DB에/잠금 해제 액세스를 고정하려면 다음 코드를 사용하고

, 명시 적으로 sem_remove을 사용하여 해당 세마포어를 제거해야합니까? 아니면 PHP가 sem_release 이후 자동으로 수행합니까?

세마포어를 명시 적으로 제거해야하는 경우 해당 세마포가 다른 스레드에 의해 현재 획득되어 있는지 확인하기위한 쉽고 안정적인 방법이 있습니까? 그래야 후자가 sem_release에 충돌하지 않습니까? 공유 메모리를 사용하는 것은 마음에 들지만 스레드의 수를 읽거나 쓰려면 또 다른 세마포어가 필요합니다.

답변

2

sem_removesem_get을 사용하여 다시 만들 때까지 다른 실행중인 프로세스 또는 스레드에 대한 추가 계산을 수행 할 수 없도록 지정된 세마포를 명시 적으로 삭제합니다. 예를 들어, 3 개의 프로세스가 동일한 세마포어 (1 개의 동시 액세스 만)에 액세스하려고 시도하고 첫 번째 프로세스가 두 개의 다른 프로세스를 획득하기 전에 먼저 파괴하면 두 개의 후자 프로세스가 순차적으로 실행되지 않고 동시에 실행됩니다 예상대로).

다른 실행중인 프로세스에서 더 이상 사용하지 않는다는 것을 알지 못한다면 실제로 sem_remove을 호출하고 싶지 않을 것입니다.

어쨌든, 귀하의 상황에서는 동시 액세스를 위해 DB 자체에 의존하는 것이 좋습니다. DB에 하나의 항목 만 작성해야하는 경우 트랜잭션을 사용하십시오. MySQL의 MyISAM 엔진과 같은 트랜잭션을 지원하지 않는 DB를 사용하고 있다면 트랜잭션을 지원하는 엔진으로 전환하거나 MyISAM의 특정 경우에 atomic operations을 사용해보십시오.