并发锁(一):为什么要加锁

举报
仙士可 发表于 2023/06/14 11:33:25 2023/06/14
【摘要】 终于下定决心写这系列的文章了,这系列的文章将从零开始,一步步了解并发下,锁的产生,类别,以及锁的实现并发数据混乱首先我们看这样一段代码:<?php/** * Created by PhpStorm. * User: tioncico * Date: 19-7-8 * Time: 下午8:31 */$num = file_get_contents('num.txt');//记录每次访问的值fi...

终于下定决心写这系列的文章了,这系列的文章将从零开始,一步步了解并发下,锁的产生,类别,以及锁的实现

并发数据混乱

首先我们看这样一段代码:

<?php
/**
 * Created by PhpStorm.
 * User: tioncico
 * Date: 19-7-8
 * Time: 下午8:31
 */
$num = file_get_contents('num.txt');
//记录每次访问的值
file_put_contents('./log.log',$num.PHP_EOL,FILE_APPEND);
echo $num.PHP_EOL;
file_put_contents('num.txt',$num+1);
复制

这是一段逻辑很简单的代码,首先获取num.txt的数据,然后输出,再进行+1写入,运行如下:

这个道理很简单,只要运行了,自然就是+1,运行2次就是+2,那么,假如同时执行2次,是+2还是+1?同时执行3次?10次?100次呢?

我们通过ab进行压力测试,验证下:

首先,查看当前数字:

tioncico@tioncico-PC:~/PhpstormProjects/lock$ cat ./num.txt 
13
复制

然后,进行并发访问:

tioncico@tioncico-PC:~/PhpstormProjects/lock$ ab -n10 -c10 http://x.cn/
复制

得到结果:

tioncico@tioncico-PC:~/PhpstormProjects/lock$ cat ./num.txt 
22
复制

很明显,理论上13+10=23,而这里却是22,查看日志可发现:

tioncico@tioncico-PC:~/PhpstormProjects/lock$ cat log.log 
13
14
14
15
16
17
18
19
20
21
复制

可看到,有2次并发访问时,获得的数字是一样的,都是14,导致了两次14+1为15,第二次读取的数据明显有误,我们继续测试一遍,发现num.txt变成了1:

tioncico@tioncico-PC:~/PhpstormProjects/lock$ cat num.txt 
1tioncico@tioncico-PC:~/PhpstormProjects/lock$
复制

查看log.log,发现:

在前面的时候,数据有很多重复,然后到35的时候,突然丢失了数据,变成了0+1,这是为什么呢?

    1:在并发情况下,A客户端和B客户端同时请求,然后同时获得了相同的数据27,所以这2个进程同时获取到了27,又同时写入了28的这个数字,导致了数据重复读取,重复写入

   2:在并发情况,A客户端和B客户端同时写入,如果是覆盖写入方式,可能会出现写入数据为空的情况,如果是追加写入,可能会出现数据冲突的情况

很明显,并发下,问题是一定有的,这个时候,该怎么解决呢?

并发下,同时访问数据会出现错误,那么,如果我不同时访问,当并发来的时候,同一时间只允许同一时间访问,这样问题不就没了?

这样是没错的,那该怎么限制呢?

这个时候,就需要用到  "锁"了

锁是一种数据保护机制,可允许某一个线程(进程)进行操作锁,当文件锁上时,其他线程(进程)根据锁的性质(读写锁,阻塞非阻塞)

其他进程会等待锁的进程操作结束,关闭锁,才可以操作该文件

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。