php 高并发的计数器 排它型锁定
php计数器原理很简单.将数据写入到文本中.然后读出来加1 再写进去.
不过遇到高并发就完蛋了.我有两种办法能解决这个问题.
方法一.利用sqlite数据库实现高并发(节假日统计用的这个方法)
<?php
header("content-Type: text/html; charset=utf-8");
//应用举例
require_once("Sqlite.class.php");
//创建实例
$DB=new SQLite("count.db"); //这个数据库文件名字任意
//创建数据库表。
//$DB->query("create table count(id integer primary key,name varchar(50),value integer)");
$name="count";
echo docount($name,1);
function docount($name="",$num=0){
global $DB;$num=intval($num);$oldnum=1;
$name=trim($name);
$count=$DB->getone("select value from count where name="".$name.""");
if(!empty($count) && $count["value"]>0){
if(empty($num)){ return $count["value"];}
$oldnum=$count["value"];
}
if(empty($num) || empty($count)){
$DB->query("insert into count(name,value) values("".$name."","".$oldnum."")");
return $oldnum;
}else{
$newnum=$oldnum+$num;
$DB->query("update count set value=value +".$num." where name="".$name.""");
return $oldnum;
}
}
?>
完整代码:https://gitee.com/web/codes/8sovg2j4id736panczykx42
方法二.php文件排它型锁定实现高并发
<?php
$name="count";
echo docount($name,1);
function docount($name="",$num=0){
$num=intval($num);$oldnum=1;
$name=trim($name);
$file="./count/".$name.".txt";
$fp = fopen($file, "a+");
if (flock($fp, LOCK_EX)) {// 进行排它型锁定
$oldnum = trim(fgets($fp,4096));
$oldnum = intval($oldnum);
if($num>0){
$newnum=intval($num+$oldnum);
ftruncate($fp, 0); //将文件截断到给定的长度
fseek($fp, 0, SEEK_SET);
fwrite($fp, $newnum);
fflush($fp); //将缓冲内容输出到文件
}
flock($fp, LOCK_UN); // 释放锁定
fclose($fp);
return $newnum;
} else {
fclose($fp);
return $oldnum;
}
}
?>
两种方法实现的效果基本上一样.不过还是感觉排它型锁定肯定计数上会有减少. 现在还不太确定哪个效率更高计数更准确.