我的计数器有问题。我需要计算两个变量,用|分隔,但有时计数器不会增加变量的值。
numeri.txt(柜台):
5240|593389
这是PHP脚本:
$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天之后,计数器没有计算大约50次展示(“|”之后的数字)
如何修复代码?
答案 0 :(得分: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.