PHP通过加锁实现并发情况下抢码功能


Posted in PHP onAugust 10, 2016

需求:抢码功能

要求:

1、特定时间段才开放抢码;

2、每个时间段放开的码是有限的;

3、每个码不允许重复;

实现:

1、在不考虑并发的情况下实现:

function get_code($len){
$CHAR_ARR = array('1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','X','Y','Z','W','S','R','T');
$CHAR_ARR_LEN = count($CHAR_ARR) - 1;
$code = '';
while(--$len > 0){ $code .= $CHAR_ARR[rand(0,$CHAR_ARR_LEN)]; }
return $code;
}
$pdo = new PDO('mysql:host=localhost;dbname=ci_test','root','root');
//查询当前时间已发放验证码数量
$code_num_rs = $pdo->query("SELECT COUNT(*) as sum FROM code_test");
$code_num_arr = $code_num_rs->fetch(PDO::FETCH_ASSOC);
$code_num = $code_num_arr['sum'];
if($code_num < 1){<br> sleep(2); //暂停2秒
$code = get_code(6);
var_dump( $pdo->query("INSERT INTO code_test (code,create_time) VALUES ('$code',".time().")") );
}

上述代码默认满足当前是开放时间,和码是不重复的; 

     在不考虑并发情况下流程:

1)选查询当前数据库发放的验证码数量;

2)如果还有名额,则生成验证码,插入到数据库,返回验证码到客户端;

3)如果已满;则返回提示,已无名额;

2、并发情况下实现:

那么看下上面代码在并发情况下得到的结果:

测试并发,可以使用apache benchmark来测试,apache benchmark是APACHE旗下的HTTP SERVER的性能评测工具,通过cmd进入到apche的bin目录下,通过ab命令调用,如:ab -c 并发数量 -n 总访问量 url

cb -c 100 -n 100 http://localhost/php_mulit.php

这样就是100个用户同事去抢1个名额,在查询的时候,每个用户都查询到还有一个名额,则会去生成验证码,插入数据库,返回验证码;这样就造成了验证码发多了。事实上,运行完该命令,数据库多了13条记录,而不是一条。

怎么避免这情况发生呢? 

     可以通过加排他锁来锁定判断到插入这个过程,保证这个判断流程任意一时间只有一个进程在运行。实现如下:

//生成码
function get_code($len){
$CHAR_ARR = array('1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','X','Y','Z','W','S','R','T');
$CHAR_ARR_LEN = count($CHAR_ARR) - 1;
$code = '';
while(--$len > 0){ $code .= $CHAR_ARR[rand(0,$CHAR_ARR_LEN)]; }
return $code;
}
$pdo = new PDO('mysql:host=localhost;dbname=ci_test','root','root');
$fp = fopen('lock.txt','r');
//通过排他锁 锁定该过程
if(flock($fp,LOCK_EX)){
//查询当前时间已发放验证码数量
$code_num_rs = $pdo->query("SELECT COUNT(*) as sum FROM code_test");
$code_num_arr = $code_num_rs->fetch(PDO::FETCH_ASSOC);
$code_num = $code_num_arr['sum'];
if($code_num < 1){
sleep(2);
$code = get_code(6);
var_dump( $pdo->query("INSERT INTO code_test (code,create_time) VALUES ('$code',".time().")") );
}
flock($fp,LOCK_UN);
fclose($fp);
}

通过flock函数来锁定该过程。

更多flock信息可以参考php手册:http://php.net/manual/zh/function.flock.php

再次运行

cb -c 100 -n 100 http://localhost/php_mulit.php

数据库只增加了一条记录,保证了并发情况下数据的正确。

以上所述是小编给大家介绍的PHP通过加锁实现并发情况下抢码功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

PHP 相关文章推荐
echo, print, printf 和 sprintf 区别
Dec 06 PHP
php md5下16位和32位的实现代码
Apr 09 PHP
无法在发生错误时创建会话,请检查 PHP 或网站服务器日志,并正确配置 PHP 安装(win+linux)
May 05 PHP
如何使用jQuery+PHP+MySQL来实现一个在线测试项目
Apr 26 PHP
PHP仿微信多图片预览上传实例代码
Sep 13 PHP
php 使用fopen函数创建、打开文件详解及实例代码
Sep 24 PHP
详谈PHP中的密码安全性Password Hashing
Feb 04 PHP
php防止sql注入的方法详解
Feb 20 PHP
PHP实现的大文件切割与合并功能示例
Apr 10 PHP
PHP排序算法之堆排序(Heap Sort)实例详解
Apr 21 PHP
php使用pthreads v3多线程实现抓取新浪新闻信息操作示例
Feb 21 PHP
PDO实现学生管理系统
Mar 21 PHP
PHP身份证校验码计算方法
Aug 10 #PHP
PHP5.4起内置web服务器使用方法
Aug 09 #PHP
PHP Filter过滤器全面解析
Aug 09 #PHP
学习PHP Cookie处理函数
Aug 09 #PHP
利用PHP命令行模式采集股票趋势信息
Aug 09 #PHP
PHP怎样用正则抓取页面中的网址
Aug 09 #PHP
php阳历转农历优化版
Aug 08 #PHP
You might like
《心理测量者3》剧场版动画预告
2020/03/02 日漫
Dedecms常用函数解析
2008/02/01 PHP
php 批量添加多行文本框textarea一行一个
2014/06/03 PHP
PHP设计模式之简单投诉页面实例
2016/02/24 PHP
php读取torrent种子文件内容的方法(测试可用)
2016/05/03 PHP
php中文乱码问题的终极解决方案汇总
2017/08/01 PHP
Jquery index()方法 获取相应元素索引值
2012/10/12 Javascript
利用jQuery的deferred对象实现异步按顺序加载JS文件
2013/03/17 Javascript
js的正则test,match,exec详细解析
2014/01/29 Javascript
DEDECMS如何为文章添加HOT NEW标志图片
2015/08/14 Javascript
基于JavaScript实现仿京东图片轮播效果
2015/11/06 Javascript
利用AJAX实现WordPress中的文章列表及评论的分页功能
2016/05/17 Javascript
javascript实现简单的可随机变色网页计算器示例
2016/12/30 Javascript
Babel 入门教程学习笔记
2018/06/13 Javascript
vue实现组件之间传值功能示例
2018/07/13 Javascript
element vue Array数组和Map对象的添加与删除操作
2018/11/14 Javascript
JS跨域请求的问题解析
2018/12/03 Javascript
mockjs+vue页面直接展示数据的方法
2018/12/19 Javascript
解决vue项目运行npm run serve报错的问题
2020/10/26 Javascript
[01:20]PWL S2开团时刻第三期——团战可以输 蝙蝠必须死
2020/11/26 DOTA
快速入手Python字符编码
2016/08/03 Python
python线程的几种创建方式详解
2019/08/29 Python
PyCharm导入python项目并配置虚拟环境的教程详解
2019/10/13 Python
Python实现鼠标自动在屏幕上随机移动功能
2020/03/14 Python
HTML5中的Web Notification桌面右下角通知功能的实现
2018/04/19 HTML / CSS
Html5导航栏吸顶方案原理与对比实现
2020/06/10 HTML / CSS
英国第二大营养品供应商:Vitabiotics
2016/10/01 全球购物
MATCHESFASHION.COM法国官网:英国奢侈品零售商
2018/01/04 全球购物
蒙蒂塞罗商店:Monticello Shop
2018/11/25 全球购物
linux面试题参考答案(11)
2016/11/26 面试题
面试求职的个人自我评价
2013/11/16 职场文书
我爱读书演讲稿
2014/05/07 职场文书
单位员工收入证明样本
2014/10/09 职场文书
学校体育节班级口号
2015/12/25 职场文书
Python实现信息轰炸工具(再也不怕说不过别人了)
2021/06/11 Python
Python万能模板案例之matplotlib绘制直方图的基本配置
2022/04/13 Python