2013-04-21 1 views
1

카운터에 문제가 있습니다. |로 분리 된 두 변수를 계산해야하지만 때로는 카운터가 변수의 값을 증가시키지 않습니다.flock()을 사용한 PHP 카운터 문제

numeri.txt (카운터) : 나는 올바른 값으로 카운터를 설정

$filename="numeri.txt"; 
$fp=fopen($filename,"r"); 
if(!flock($fp,LOCK_SH)) 
{ 
    while(true) 
    { 
     usleep(100000); 
     if(flock($fp,LOCK_SH)) 
     { 
      break; 
     } 
    } 
} 
$contents=fread($fp,filesize($filename)); 
flock($fp,LOCK_UN); 
fclose($fp); 
$fp=fopen($filename,'a'); 
if(!flock($fp,LOCK_EX)) 
{ 
    while(true) 
    { 
     usleep(100000); 
     if(flock($fp,LOCK_EX)) 
     { 
      break; 
     } 
    } 
} 
ftruncate($fp,0); 
$contents=explode("|",$contents); 
$clicks=$contents[0]; 
$impressions=$contents[1]+1; 
fwrite($fp,$clicks."|".$impressions); 
flock($fp,LOCK_UN); 
fclose($fp); 

하지만 3-4 후 일 카운터 :

5240|593389

이것은 PHP 스크립트입니다 약 50 회의 노출 수를 계산하지 않았습니다 ("|"뒤에 오는 숫자)

코드 수정 방법은 무엇입니까?

답변

2

두 가지 문제 : 여전히 읽기를 할 수있는 기회가

1), 다른 프로세스는이 프로세스가 파일을 작성, 파일을 작성합니다. 밀리 초 타이밍이 필요하지만 가능합니다.

2) 실제로 "열린"작동을 확인하지 않습니다. 실패 할 수 있습니다.

해결 방법은 먼저 열려있는 실패를 확인하고 다시 시도한 다음 두 번째로 단독 잠금을 수행하는 것입니다. 구절을 끈 코드 :

while (!$fh = fopen($file, 'c+')) { // Read write, do not truncate, place pointer at start. 
    usleep(100000); 
} 
while (!flock(LOCK_EX)) { 
    usleep(100000); 
} 
$content = fread(); 
// Process content... 
ftruncate(); 
fseek(0); // Or frewind(); 
fwrite(); 
fclose(); // Also releases the lock. 
+1

fopen과 flock 모두에서 usleep() 함수를 사용해야합니까? – Megadv

+1

둘 다 실패 할 수 있으므로 예. 이상적으로는 카운터가 반복적으로 멈추는 것이 좋습니다. – Robbie

+0

나는 그것을했다. 그러나 지금, 8 시간 후에 그것은 2 개의 가치를 더 센다. 왜? – Megadv