php并发
bool flock ( int handle, int operation [, int &wouldblock] );
flock() 操作的 handle 必须是一个已经打开的文件指针。operation 可以是以下值之一:
- 要取得共享锁定(读取程序),将 operation 设为 LOCK_SH(PHP 4.0.1 以前的版本设置为 1)
- 要取得独占锁定(写入程序),将 operation 设为 LOCK_EX(PHP 4.0.1 以前的版本中设置为 2)
- 要释放锁定(无论共享或独占),将 operation 设为 LOCK_UN(PHP 4.0.1 以前的版本中设置为 3)
- 如果你不希望 flock() 在锁定时堵塞,则给 operation 加上 LOCK_NB(PHP 4.0.1 以前的版本中设置为 4)
建两个文件
(1) a.php
$file = "temp.txt"; $fp = fopen($file , 'w'); if(flock($fp , LOCK_EX)){ fwrite($fp , "abc\n"); sleep(10); fwrite($fp , "123\n"); flock($fp , LOCK_UN); } fclose($fp); |
(2) b.php
$file = "temp.txt"; $fp = fopen($file , 'r'); echo fread($fp , 100); fclose($fp); |
运行 a.php 后,马上运行 b.php ,可以看到输出:
abc
等 a.php 运行完后运行 b.php ,可以看到输出:
abc
123
显然,当 a.php 写文件时数据太大,导致时间比较长时,这时 b.php 读取数据不完整
修改 b.php 为:
$file = "temp.txt"; $fp = fopen($file , 'r'); if(flock($fp , LOCK_EX)){ echo fread($fp , 100); flock($fp , LOCK_UN); } else{ echo "Lock file failed...\n"; } fclose($fp); |
运行 a.php 后,马上运行 b.php ,可以发现 b.php 会等到 a.php 运行完成后(即 10 秒后)才显示:
abc
123
读取数据完整,但时间过长,他要等待写锁释放。
修改 b.php 为:
$file = "temp.txt"; $fp = fopen($file , 'r'); if(flock($fp , LOCK_SH | LOCK_NB)){ echo fread($fp , 100); flock($fp , LOCK_UN); } else{ echo "Lock file failed...\n"; } fclose($fp); |
运行 a.php 后,马上运行 b.php ,可以看到输出:
Lock file failed…
证明可以返回锁文件失败状态,而不是向上面一样要等很久。
结论:
建议作文件缓存时,选好相关的锁,不然可能导致读取数据不完整,或重复写入数据。
file_get_contents 好像选择不了锁,不知道他默认用的什么锁,反正和不锁得到的输出一样,是不完整的数据。
我是要做文件缓存,所以只需要知道是否有写锁存在即可,有的话就查数据库就可以了。
测试环境:Linux(Ubuntu 6) , PHP 5.1.2 , Apache 2
再转:
文件的锁一般这么使用:
- $fp = fopen("filename", "a");
- flock($fp, LOCK_SH) or die("lock error")
- $str = fread($fp, 1024);
- flock($fp, LOCK_UN);
- fclose($fp);
注意fwrite之后,文件立即就被更新了,而不是等fwrite然后fclose之后文件才会更新,这个可以通过在fwrite之后fclose之前读取这个文件进行检查
但是什么时候使用lock_ex什么时候使用lock_sh呢?
读的时候:
如果不想出现dirty数据,那么最好使用lock_sh共享锁。可以考虑以下三种情况:
1. 如果读的时候没有加共享锁,那么其他程序要写的话(不管这个写是加锁还是不加锁)都会立即写成功。如果正好读了一半,然后被其他程序给写了,那么读的后一半就有可能跟前一半对不上(前一半是修改前的,后一半是修改后的)
2. 如果读的时候加上了共享锁(因为只是读,没有必要使用排他锁),这个时候,其他程序开始写,这个写程序没有使用锁,那么写程序会直接修改这个文件,也会导致前面一样的问题
3. 最理想的情况是,读的时候加锁(lock_sh),写的时候也进行加锁(lock_ex),这样写程序会等着读程序完成之后才进行操作,而不会出现贸然操作的情况
写的时候:
如果多个写程序不加锁同时对文件进行操作,那么最后的数据有可能一部分是a程序写的,一部分是b程序写的
如果写的时候加锁了,这个时候有其他的程序来读,那么他会读到什么东西呢?
1. 如果读程序没有申请共享锁,那么他会读到dirty的数据。比如写程序要写a,b,c三部分,写完a,这时候读读到的是a,继续写b,这时候读读到的是ab,然后写c,这时候读到的是abc.
2. 如果读程序在之前申请了共享锁,那么读程序会等写程序将abc写完并释放锁之后才进行读。
转载:http://www.cnblogs.com/chenwenbiao/archive/2011/08/01/2123905.html
php并发的更多相关文章
- .Net多线程编程—并发集合
并发集合 1 为什么使用并发集合? 原因主要有以下几点: System.Collections和System.Collections.Generic名称空间中所提供的经典列表.集合和数组都不是线程安全 ...
- [ 高并发]Java高并发编程系列第二篇--线程同步
高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...
- [高并发]Java高并发编程系列开山篇--线程实现
Java是最早开始有并发的语言之一,再过去传统多任务的模式下,人们发现很难解决一些更为复杂的问题,这个时候我们就有了并发. 引用 多线程比多任务更加有挑战.多线程是在同一个程序内部并行执行,因此会对相 ...
- 关于如何提高Web服务端并发效率的异步编程技术
最近我研究技术的一个重点是java的多线程开发,在我早期学习java的时候,很多书上把java的多线程开发标榜为简单易用,这个简单易用是以C语言作为参照的,不过我也没有使用过C语言开发过多线程,我只知 ...
- 如何在高并发环境下设计出无锁的数据库操作(Java版本)
一个在线2k的游戏,每秒钟并发都吓死人.传统的hibernate直接插库基本上是不可行的.我就一步步推导出一个无锁的数据库操作. 1. 并发中如何无锁. 一个很简单的思路,把并发转化成为单线程.Jav ...
- Java多线程基础——对象及变量并发访问
在开发多线程程序时,如果每个多线程处理的事情都不一样,每个线程都互不相关,这样开发的过程就非常轻松.但是很多时候,多线程程序是需要同时访问同一个对象,或者变量的.这样,一个对象同时被多个线程访问,会出 ...
- 多线程的通信和同步(Java并发编程的艺术--笔记)
1. 线程间的通信机制 线程之间通信机制有两种: 共享内存.消息传递. 2. Java并发 Java的并发采用的是共享内存模型,Java线程之间的通信总是隐式执行,通信的过程对于程序员来说是完全透 ...
- 伪共享(false sharing),并发编程无声的性能杀手
在并发编程过程中,我们大部分的焦点都放在如何控制共享变量的访问控制上(代码层面),但是很少人会关注系统硬件及 JVM 底层相关的影响因素.前段时间学习了一个牛X的高性能异步处理框架 Disruptor ...
- 编写高质量代码:改善Java程序的151个建议(第8章:多线程和并发___建议126~128)
建议126:适时选择不同的线程池来实现 Java的线程池实现从根本上来说只有两个:ThreadPoolExecutor类和ScheduledThreadPoolExecutor类,这两个类还是父子关系 ...
- 理解Storm并发
作者:Jack47 PS:如果喜欢我写的文章,欢迎关注我的微信公众账号程序员杰克,两边的文章会同步,也可以添加我的RSS订阅源. 注:本文主要内容翻译自understanding-the-parall ...
随机推荐
- (转)Paper list of Meta Learning/ Learning to Learn/ One Shot Learning/ Lifelong Learning
Meta Learning/ Learning to Learn/ One Shot Learning/ Lifelong Learning 2018-08-03 19:16:56 本文转自:http ...
- (转)Awesome Courses
Awesome Courses Introduction There is a lot of hidden treasure lying within university pages scatte ...
- Perceptual Losses for Real-Time Style Transfer and Super-Resolution and Super-Resolution 论文笔记
Perceptual Losses for Real-Time Style Transfer and Super-Resolution and Super-Resolution 论文笔记 ECCV 2 ...
- webpack用 babel将ES6转译ES5
webpack webpack.config.js配置文件 module.exports = { entry: './es6.js', // 入口文件路径 output: { filename: &q ...
- (转载)用C#实现MySQL建库及建表
最近做一个项目,为了方便用户使用,希望可以在系统初始化的时候,自动实现MySQL数据库的建库和建表操作.在网上查了很多资料都没有找到合适的,偶尔在一个国外网站上看到了相关的内容,特把实现方法整理如下: ...
- Java基础【冒泡、选择排序、二分查找】
冒泡排序的思路就是前一个和后一个进行比较,如果大的就交换位置 大的数字后浮 如 12 8 5 31 第一轮 8 5 12 31 第二轮 5 8 ...
- Xilinx_ISE 14.7 Win10 闪退
打开D:\Xilinx\14.7\ISE_DS\ISE\lib\nt64 将libPortabilityNOSH.dll 重命名为libPortability.dll,替换原libPortabilit ...
- js点击显示隐藏
这个栗子…… 可以不吃,先预设一个变量表示div的状态,例子中0是显示的,一开始是隐藏的.当点击时判断状态是显示0的还是隐藏1的:如果是显示的就把div隐藏,再把变量改变为1.再次点击时把会判断到变量 ...
- HTML-CSS-JS-JQ常用知识点总结
html:展示文件 标签:<html><head><title></title><meta><link><style> ...
- Java单例设计模式(实现Java的一个类只有一个对象)
单例设计模式的定义:单例设计模式是一种软件设计模式,在它的核心包含一个称为单例类的核心类. 核心便是希望一个类只有一个对象. 如何实现类在内存中只有一个对象呢? 第一步:构造私有:第二步:本身提供一 ...