【问题标题】:PHP counter issue using flock()使用flock()的PHP计数器问题
【发布时间】:2013-04-21 10:49:53
【问题描述】:

我的计数器有问题。我需要计算两个变量,用 | 分隔,但有时计数器不会增加变量的值。

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 次展示(“|”后面的数字)

如何修复代码?

【问题讨论】:

    标签: php counter flock


    【解决方案1】:

    两个问题:

    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.
    

    【讨论】:

    • fopen 和flock 都必须使用usleep() 函数吗?
    • 两者都可能失败,所以是的。理想情况下,您将拥有一个永远停止循环的计数器。
    • 我做到了,但现在,8 小时后,它又增加了两个值。为什么?
    • 因为你调用它的次数是你应该调用的两倍(例如测试它?)或者你比较两个的东西太少了?它可以仍然计入(如果它出错的话),但看不到它怎么可以计入...
    • 现在应该是 600404 但它是 600379(少了 25 个)。我在所有功能(如 fopen、ftruncate、flock 等)中使用了 while true 和 usleep。我该怎么办?
    猜你喜欢
    • 1970-01-01
    • 2013-05-23
    • 2012-02-28
    • 2011-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多