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 相关文章推荐
php面向对象 字段的声明与使用
Jun 14 PHP
php中使用__autoload()自动加载未定义类的实现代码
Feb 06 PHP
Zend studio文件注释模板设置方法
Sep 29 PHP
PHP实现删除字符串中任何字符的函数
Aug 11 PHP
PHP安装threads多线程扩展基础教程
Nov 17 PHP
PHP简单的MVC框架实现方法
Dec 01 PHP
php数组分页实现方法
Apr 30 PHP
Yii2中如何使用modal弹窗(基本使用)
May 30 PHP
php实现登陆模块功能示例
Oct 20 PHP
PHP+jquery+CSS制作头像登录窗(仿QQ登陆)
Oct 20 PHP
php微信公众号开发之校园图书馆
Oct 20 PHP
PHP检查文件是否存在,不存在自动创建及读取文件内容操作示例
Jan 23 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
PHP 基于文件头的文件类型验证类函数
2012/05/01 PHP
php处理文件的小例子(解压缩,删除目录)
2013/02/03 PHP
php返回json数据函数实例
2014/10/09 PHP
9个比较实用的php代码片段
2016/03/15 PHP
基于PHP实现商品成交时发送短信功能
2016/05/11 PHP
php单链表实现代码分享
2016/07/04 PHP
PHP实现简易blog的制作
2016/10/24 PHP
javascript RadioButtonList获取选中值
2009/04/09 Javascript
img onload事件绑定各浏览器均可执行
2012/12/19 Javascript
struts2+jquery+json实现异步加载数据(自写)
2013/06/24 Javascript
基于jQuery的JavaScript模版引擎JsRender使用指南
2014/12/29 Javascript
详解JavaScript ES6中的Generator
2015/07/28 Javascript
jquery实现仿JqueryUi可拖动的DIV实例
2015/07/31 Javascript
Javascript获取统一管理的提示语(message)
2016/02/03 Javascript
JS原型链 详解及示例代码
2016/09/06 Javascript
H5用户注册表单页 注册模态框!
2016/09/17 Javascript
原生JS实现的放大镜效果实例代码
2016/10/15 Javascript
bootstrap模态框消失问题的解决方法
2016/12/02 Javascript
ReactNative Image组件使用详解
2017/08/07 Javascript
详解react-router4 异步加载路由两种方法
2017/09/12 Javascript
详解Vue This$Store总结
2018/12/17 Javascript
基于Layui自定义模块的使用方法详解
2019/09/14 Javascript
layui监听单元格编辑前后交互的例子
2019/09/16 Javascript
JavaScript 事件代理需要注意的地方
2020/09/08 Javascript
[54:56]DOTA2上海特级锦标赛主赛事日 - 5 总决赛Liquid VS Secret第三局
2016/03/06 DOTA
python安装numpy&amp;安装matplotlib&amp; scipy的教程
2017/11/02 Python
python安装模块如何通过setup.py安装(超简单)
2018/05/05 Python
django之使用celery-把耗时程序放到celery里面执行的方法
2019/07/12 Python
Django框架自定义模型管理器与元选项用法分析
2019/07/22 Python
基于python3抓取pinpoint应用信息入库
2020/01/08 Python
盛大二次面试题
2016/11/18 面试题
长安大学毕业生自我鉴定
2014/01/17 职场文书
《诚实与信任》教学反思
2014/04/10 职场文书
预防艾滋病宣传标语
2014/06/25 职场文书
2014入党积极分子批评与自我批评思想报告
2014/10/06 职场文书
Python matplotlib可视化之绘制韦恩图
2022/02/24 Python