zoukankan      html  css  js  c++  java
  • thinkphp并发 阻塞模式与非阻塞模式

    结构代码

    public function index(){
    
            $fp = fopen("lock.txt", "w+");
            if(flock($fp,LOCK_EX))   
            {
                // 处理商品数据
              
                flock($fp,LOCK_UN);
            }
            fclose($fp);
        }

    概述:

    1.首先,读写方式打开或者创建文件lock.txt文件

    2.给lock.txt文件上 "独占锁",上锁成功后就可以进行下一步"处理订单商品数据了"

    3.处理完数据后,要"释放锁”,以及fclose关闭打开的文件

    注意:给文件“独占锁”后,如果再没有里面的“释放锁”,就没有下一个"轮回" 

    fopen详细介绍:http://www.w3school.com.cn/php/func_filesystem_fopen.asp

    flock详细介绍:http://www.w3school.com.cn/php/func_filesystem_flock.asp

    fclose详细介绍:http://www.w3school.com.cn/php/func_filesystem_fclose.asp

    详细代码

    namespace appindexcontroller;
    use thinkController;
    use thinkCache;
    
    class Index extends Controller
    {
       
        /**
         * 首页
         * */
        public function index(){
    
            $fp = fopen("lock.txt", "w+");
            if(flock($fp,LOCK_EX))   //锁定当前指针,,,
            {
                //..处理订单
    
                $stock = $this->findStock();
                if($stock > 0){
                    $this->setDec();
                }else{
                    return '抢购失败';
                }
                return $stock;
                flock($fp,LOCK_UN);
            }
            fclose($fp);
        }
    
        /**
         * 查询数据库库存
         * */
        public function findStock(){
            $res = db('info')->where('id',1)->field('stock')->lock(true)->find();
            return $res['stock'];
        }
    
        /**
         * 减少库存操作
         * */
        public function setDec(){
            $res = db('info')->where('id',1)->setDec('stock',1);
            return $res;
        }
    }

    总结有点:

    1.可以解决并发问题,库存为负数的情况。

    2.并发是,大家都在等待。当所有并发结束后,才会获得跳转(这也是缺点,如果处理1000条并发,需要时间15s,那么所有参加的人都需要等待15s后才进入下一个页面)

    非阻塞模式

    结构代码,与阻塞模式不同的地方 LOCK_NB (如果不希望 flock() 在锁定时堵塞,则给 lock 加上 LOCK_NB)

    代码:

     public function index(){
            $fp = fopen("lock.txt", "w+");
            if(flock($fp,LOCK_EX | LOCK_NB))
            {
                $stock = $this->findStock();
                if($stock > 0){
                    $this->setDec();
                }else{
                    return '抢购失败';
                }
                $this->setDec();
                return $stock;
                flock($fp,LOCK_UN);
            }
            else
            {
                echo "抢购失败,要不再试试";
            }
    
            fclose($fp);
        }

    总结:

    1.相比阻塞模式的时间等待,非阻塞模式则更加人性化很多

    2.如果有有很多人都进入抢购,人太多就会直接进入第二个动作(“抢购失败界面”)。部分人就会进入第一个动作(“抢购候选名单”), 下一个步骤1.抢购成功 或者2 抢购失败

  • 相关阅读:
    VCL源码修改立即生效
    让C++控制台程序停下来,实现暂停功能
    Ubuntu系统中初次下载Android源码的一点经验
    理解SetCapture、ReleaseCapture、GetCapture(控制了消息发往哪个窗口,即消息窗口)
    又发现2个高人写的Delphi图文并茂的消息研究
    0x0118消息就是WM_SYSTIMER
    QT信号槽与Delphi事件的对比
    使用VS2005安装和编译QT4.53源码
    使用SmsManager服务群发短信
    减小VirtualBox虚拟硬盘文件的大小
  • 原文地址:https://www.cnblogs.com/wesky/p/6672528.html
Copyright © 2011-2022 走看看