2016-11-03 6 views
3

예약 서비스에 사용되는 데이터베이스 테이블에 삽입하기 위해 액세스 제어를 구현했습니다. 그것은 얼마 동안 괜찮 았는데, sem_get() 후에 sem_release()을 호출 했음에도 불구하고 sem_get() 함수가 실패합니다.PHP sem_get 함수가 실패했습니다.

case 'room': 
    $key = "room"; 
    $semaphore = sem_get($key, 1, 0666, 1); 
    if ($semaphore) { 
     sem_acquire($semaphore); 
     //do some stuff 
     if ($already_reserved_rooms < $max_rooms) { 
      $return="ok"; 
      sem_release($semaphore); 
      return $return; 
     } 
      sem_release($semaphore); 
    } 
    else { 
     //send me mail that semaphore failed 
    } 

    return 'no rooms'; 
    break; 

sem_remove()으로 전화해야합니까?

나는 this 사이트의 단계를 따른다.

+2

, 그것은 경고를 기록합니다. 우리에게 경고를 보여주십시오. –

+0

'sem_remove'에 대한 설명에서 말하자면, ** 모든 ** 프로세스에서 세마포어로 완전히 완료되기 전에 당신이하고 싶은 일이 분명하지 않습니다. – apokryfos

+0

답장을 보내 주셔서 감사합니다. SysV semaphore 5 (key 0x214)가 현재 획득되지 않았습니다. – JokerDev

답변

0

제거 세마포어 당신이 세마포어 세트 완료

예, 당신이 호출해야 sem_remove(). 그렇지 않으면 세마포어 집합을 제거 할 때까지 시스템에 지속됩니다. 세마포어의 수가 SEMMNS 한계보다 작을 때 그러나, 세마포어 세트가 지속 사실은 아무 문제가 발생하지 않습니다 :

SEMMNS 세마포어의 수에 시스템 전체 제한 정책 의지 (리눅스,이 한도는 /proc/sys/kernel/sem의 두 번째 필드를 통해 읽고 수정할 수 있습니다.

sem_remove()은 즉시이 세마포어를 사용하여 차단 된 모든 프로세스를 각성시키는 세마포어 집합을 제거합니다.

그런데 ipcrm 명령을 사용하여 명령 줄에서 세마포를 제거하고 ipcs 명령을 사용하여 IPC 기능 (세마포 포함)에 대한 정보를 표시 할 수 있습니다.

해제 세마포어

당신은 자동 해제 플래그 (sem_get의 4 번째 매개 변수)에있는 동안 sem_release()를 호출 할 필요가 없습니다. 그러나 획득 한 "잠금"이 필요하지 않는 한 세마포어를 해제하는 것이 좋습니다.

sem_release()은 내부 세마포어 값을 증가시킵니다. 잠금 해제 작업이라고 생각하면 sem_acquire()의 반대입니다.

sem_get() 실패

sem_get() 함수는 다음과 같은 경우 FALSE

  • PHP 파라미터 해석 실패 (E_ERROR)을 리턴한다;
  • 세마포어가 있지만 호출하는 프로세스에 집합에 액세스 할 수있는 권한이 없습니다 (E_WARNING).
  • 메모리 할당 오류 (E_WARNING);
  • 세마포어 세트의 최대 수, 또는 세마포어의 시스템 전체의 최대 수는 예 sem_get 각각에서

(E_WARNING) 오류 또는 경고를 기록 초과.따라서 은 문제의 근본 원인을 찾으려면 로그을 확인해야합니다.

코드가 얼마 동안 작동하기 때문에 매개 변수 구문 분석 문제가 아니며 사용 권한이 아닙니다. 메모리 할당 문제는 드뭅니다. 따라서 세마포어 수 제한을 모두 벗어날 가능성이 큽니다. 참조 용으로 semget의 man 페이지를 확인하십시오. 맨 페이지는 /proc/sys/kernel/sem을 통해 한계를 읽고 수정하는 방법을 설명합니다.

sysvsem 확장 내부 정보에 대한 자세한 내용은 this 답변을 참조하십시오.

+0

귀하의 의견을 주셔서 감사합니다,하지만 그것과 sem_release의 차이점은 무엇입니까? 그런 다음 다른 사용자가 동일한 세마포어를 공유하기를 원할 때 세마포어를 제어하는 ​​방법을 설명합니다. – JokerDev

+0

"완료되면"라고 말하면 위 코드의 끝에서 내 코드에서 sem_remove()를 호출하면 해당 프로세스가 종료 될 때 현재 획득 한 프로세스를 기다리는 다른 프로세스에 영향을 미칩니다 릴리스 할 세마포어? – JokerDev

+0

@ drupaler1,'sem_release'는 세마포어의 잠금을 해제하고,'sem_remove'는 세마포어 집합을 제거합니다. 세마포어 세트는 영구적으로 두어도되지만 요청 종료 단계 근처에서 어딘가에 제거하는 것이 오류가 발생하기 쉽습니다. 세마포어 세트로 _done하면 세마포어 세트에서 더 이상 연산을 수행 할 필요가 없다는 의미입니다. 'sem_acquire'는 세마포어가 획득 될 때까지 차단됩니다. 세마포어 집합이 존재하는 한 자유롭게 획득/해제 할 수 있습니다. sem.set을 제거하지 않아도됩니다. 업데이트 된 답변을 참조하십시오. –

0

sem_get()의 $ key 인수는 문자열로 전달하는 동안 정수입니다. ftok() 호출로 정수 키를 가져 오는 것을 고려하십시오.

그래서 다음과 같은 코드를

$key = "room"; 

교체를 고려하십시오 :`sem_get`가 실패하면

$project = "r"; // Project identifier. This must be a one character string. 
$key = ftok(__FILE__, $project);