广告 全新升级

PHP 利用文件锁处理高并发

  [复制链接]
查看43233 | 回复1662 | 2021-4-3 16:35 | 显示全部楼层 |阅读模式

利用flock()函数对文件进行加锁(排它锁),实现并发按序进行。

  flock(file,lock,block)有三个参数。

  file:已经打开的文件

  lock:锁的类型

    LOCK_SH:共享锁(读锁)

    LOCK_EX:独占锁定(排它锁,写锁)

    LOCK_UN:解锁

    LOCK_NB:如果希望在文件锁定时阻塞进程,那么需要加上该参数

  block:设置为true的时候,锁定文件时,会阻止其他进程

  下面是一个demo:

  1. class Order{

  2.     /**
  3.      * 阻塞模式(后面的进程会一直等待前面的进程执行完毕)
  4.      */
  5.     public function createOrder1(){
  6.         $file = fopen(__DIR__.'/lock.txt','w ');
  7.         //加锁
  8.         if(flock($file,LOCK_EX)){
  9.             //TODO 执行业务代码
  10.             flock($file,LOCK_UN);//解锁
  11.         }
  12.         //关闭文件
  13.         fclose($file);
  14.     }

  15.     /**
  16.      * 非阻塞模式(只要当前文件有锁存在,那么直接返回)
  17.      */
  18.     public function createOrder2(){
  19.         $file = fopen(__DIR__.'/lock.txt','w ');
  20.         //加锁
  21.         if(flock($file,LOCK_EX|LOCK_NB)){
  22.             //TODO 执行业务代码
  23.             flock($file,LOCK_UN);//解锁
  24.         }else{
  25.             //TODO 执行业务代码 返回系统繁忙等错误提示
  26.         }
  27.         //关闭文件
  28.         fclose($file);
  29.     }
  30. }
复制代码


提示:在执行fclose()的时候文件会自动解锁,所以可以省略解锁的代码。


demo:

  1. 【一】.阻塞模式:(如果其他进程已经加锁文件,当前进程会一直等其他进程解锁文件后继续执行)
  2. <?php
  3. //连接数据库
  4. $con=mysqli_connect("192.168.2.186","root","root","test");
  5. //查询商品数量是否大于0,大于0才能下单,并减少库存
  6. $fp = fopen("lock.txt", "r");
  7. //加锁
  8. if(flock($fp,LOCK_EX))
  9. {
  10.         $res=mysqli_fetch_assoc(mysqli_query($con,'SELECT total FROM shop WHERE id=1 LIMIT 1'));
  11.         if($res['total']>0){mysqli_query($con,'UPDATE shop SET total=total-1  WHERE id=1');}
  12.         //执行完成解锁
  13.         flock($fp,LOCK_UN);
  14. }
  15. //关闭文件
  16. fclose($fp);
  17. unset($res);
  18. mysqli_close($con);
  19. ?>
  20. 这种情况若是其他进程已经加锁文件,那么所有进程都会等他执行完并解锁文件后才会执行

  21. 【二】.非阻塞模式:(如果其他进程已经加锁文件,当前进程不会等其他进程解锁文件,而是走else)<?php
  22. //连接数据库
  23. $con=mysqli_connect("192.168.2.186","root","root","test");

  24. //查询商品数量是否大于0,大于0才能下单,并减少库存

  25. $fp = fopen("lock.txt", "r");
  26. //加锁
  27. if(flock($fp,LOCK_EX | LOCK_NB))
  28. {
  29.         $res=mysqli_fetch_assoc(mysqli_query($con,'SELECT total FROM shop WHERE id=1 LIMIT 1'));
  30.         if($res['total']>0){mysqli_query($con,'UPDATE shop SET total=total-1  WHERE id=1');}
  31.         //执行完成解锁
  32.         flock($fp,LOCK_UN);
  33. }else{
  34.   echo "locked file failed\n";
  35. }
  36. unset($res);
  37. mysqli_close($con);
  38. ?>
  39. 这种情况就会直接走else返回提示信息
复制代码



蓝奏链接如访问不了把lanzous换成lanzoux或lanozui
;主题回复不显示隐藏内容就刷新页面;
fan_787 | 2021-4-3 16:35 | 显示全部楼层
从此后变成食草动物,糖尿病就彻底好了。
回复

使用道具 举报

只要得了糖尿病,血糖在好,都会有并发症,
回复

使用道具 举报

匿名 单匪 | 2021-4-3 16:35 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

谢谢你的分享,受益很好,比别的文章讲解的透明,
回复

使用道具 举报

做好这3个小细节,轻松应对餐后高血糖~再也不用提心吊胆的吃饭啦~@糖尿病之友
回复

使用道具 举报

Eve丶兽性 | 2021-4-3 16:36 | 显示全部楼层
文章很好,很有助于控制血糖。谢谢!\
回复

使用道具 举报

确诊糖尿病后只有意外死。或者被它折磨几年生不如死后再惨死没有其他选择除非医疗技术彻底的治愈这是现实其他都是心灵鸡汤
回复

使用道具 举报

夏目啪啪啪 | 2021-4-3 16:36 | 显示全部楼层
人的一生中什么是快乐:吃不能吃:这活着还有什么意议:我去年查出是糖尿病:到今肉都不敢吃:感觉生活没意思,没一点乐趣:还是怎么开心怎么活:生死命中注定:本人今年48岁:还有几个48:所以只要想得开:开心过好每一天:心情好病自然好:祝我今天生日快乐:☕☕☕
回复

使用道具 举报

主食和水果是血糖升高最快的元凶,瘦肉和青菜会好些。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则