• 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 抢购失败

  • 相关阅读:
    UOJ #455 [UER #8]雪灾与外卖 (贪心、模拟费用流)
    Codeforces 482E ELCA (LCT)
    Codeforces 798D Mike and distribution (构造)
    AtCoder AGC017C Snuke and Spells
    HDU 6089 Rikka with Terrorist (线段树)
    HDU 6136 Death Podracing (堆)
    AtCoder AGC032D Rotation Sort (DP)
    jenkins+python+kubectl实现批量更新k8s镜像
    Linux 下载最新kubectl版本的命令:
    jenkins X 和k8s CI/CD
  • 原文地址:https://www.cnblogs.com/wesky/p/6672528.html
Copyright © 2020-2023  润新知