使用PHP文件锁写一个多个请求同时并发写入一个文件,要求不脏读、数据不丢失
使用PHP文件锁写一个多个请求同时并发写入一个文件,要求不脏读、数据不丢失.
//并发文件操作
function filehandle($filename,$data){
$start = 0;
$end = 3000; if(!file_exists($filename)){
return "文件不存在";
} if(!is_string($data)){
return "写入内容只能为字符串类型";
} if($fp = fopen($filename,'a')){
do{
//获取文件独占锁
$canWrite = flock($fp,LOCK_EX); if(!$canWrite){
$rand = mt_rand(1,100);
//让程序休眠随机毫秒数再试
usleep($rand*1000);
$start += $rand;
} }while(!$canWrite && $start < $end); if(!$canWrite){
//未能获得锁
return "获取文件锁失败";
}else{
fwrite($fp,$data);
} //释放锁定,关闭文件
flock($fp, LOCK_UN);
fclose($fp);
return true; }else{
return "打开文件失败";
} }
此方法的要点是当用户操作文件的时候必须获取文件的独占锁,若文件已经被锁定,则让程序休眠若干毫秒后重试,知道获得锁或者超时为止。
flock():轻便的咨询文件锁定
函数参数说明:
handle - 文件系统指针,是典型地由 fopen() 创建的 resource(资源)。
operation - 可以是以下值之一:
LOCK_SH取得共享锁定(读取的程序)。LOCK_EX取得独占锁定(写入的程序。LOCK_UN释放锁定(无论共享或独占)。
返回值:成功时返回 TRUE, 或者在失败时返回 FALSE。
方案二:
file_put_contents($filename, $data, FILE_APPEND|LOCK_EX);
int file_put_contents ( string $filename , mixed $data [, int $flags = 0 [, resource $context ]] );
函数说明:将一个字符串写入文件
参数说明:
filename - 要被写入数据的文件名。
data - 要写入的数据。类型可以是 string,array(一维) 或者是 stream 资源。
flags - flags的值可以是 以下 flag 使用 OR (|) 运算符进行的组合。
FILE_USE_INCLUDE_PATH : 在 include 目录里搜索 filename。 更多信息可参见 include_path。
FILE_APPEND : 如果文件 filename 已经存在,追加数据而不是覆盖。
LOCK_EX : 在写入时获得一个独占锁。
context - 一个 context 资源。
返回值:该函数将返回写入到文件内数据的字节数,失败时返回FALSE
(注:以上方案均未经过实际项目测试)
使用PHP文件锁写一个多个请求同时并发写入一个文件,要求不脏读、数据不丢失的更多相关文章
- 对tomcat来说,每一个进来的请求(request)都需要一个线程,直到该请求结束。
这段时间折腾了哈java web应用的压力测试,部署容器是tomcat 7.期间学到了蛮多散碎的知识点,及时梳理总结,构建良好且易理解的知识架构把它们组织起来,以备忘.对web应用开发者来说,我们很关 ...
- 一个封装HTTP请求的函数(C++)
这里封装了HTTP请求的,支持GET与POST,并支持各种参数组合,调用方式很简单使用DEVWEB::WebRequest(string(“http://www.luaie.com/”),ret);就 ...
- 接口测试入门(2)--get和post初级请求/使用httpclient做一个获取信息list的请求(需要登录才可以)
抛去测试自动化的架构来,直接写单个测试用例的思路如下: 1.获取测试case的接口,对每一个接口的请求方式(get/post/delete/put)进行分析,是否需要参数(不同的用例设置不同的参数,如 ...
- springMVC一个Controller处理所有用户请求的并发问题(转)
springMVC一个Controller处理所有用户请求的并发问题 有状态和无状态的对象基本概念: 有状态对象(Stateful Bean),就是有实例变量的对象 ,可以保存数据,是非线程安全的.一 ...
- jsp页面:一个form,不同请求提交form
需求:一个表单中有一个请求 action="url"发送数据地址: 在表单外有一个请求,请求form表单提交的数据 我们用js来写:通过每次请求传不同的action=url; 例如 ...
- 怎样使用ListView实现一个带有网络请求,解析,分页,缓存的公共的List页面来大大的提高工作效率
在寻常的开发中常常会有非常多列表页面.每做一个列表页就须要创建这个布局文件那个Adapter适配器文件等等一大堆与之相关的附属的不必要的冗余文件. 假设版本号更新迭代比較频繁,如此以往,就会使项目pr ...
- Asp.Net MVC是否针对每次请求都重新创建一个控制器实例
一.Asp.Net MVC是否针对每次请求都重新创建一个控制器实例 默认情况下,答案是确定的. ControllerBuilder类 ControllerBuilder.Current用户获取默认的控 ...
- 一个跨域请求的XSS续
之前讨论过,在解决post跨域请求时,采用iframe+本域代理页的形式,兼容性(当然是包括IE6啦)是最好的.上次提到,代理页面的作用是:执行本域下的回调函数.就是这个原因,给XSS带来了便利.详细 ...
- 利用生产者消费者模型和MQ模型写一个自己的日志系统-并发设计里一定会用到的手段
一:前言 写这个程序主要是用来理解生产者消费者模型,以及通过这个Demo来理解Redis的单线程取原子任务是怎么实现的和巩固一下并发相关的知识:这个虽然是个Demo,但是只要稍加改下Appender部 ...
随机推荐
- Django REST FrameWork中文教程3:基于类的视图
我们也可以使用基于类的视图编写我们的API视图,而不是基于函数的视图.我们将看到这是一个强大的模式,允许我们重用常用功能,并帮助我们保持代码DRY. 使用基于类的视图重写我们的API 我们将首先将根视 ...
- 使用phpExcel导出excel时,报500错
在自己本地导出excel没有问题,但是放到服务器出现500的错误! 解决方法:查看控制器引用的header文件,是否包含空格,如下: header('Pragma:public'); ...
- Linux CentOS7 安装 Mysql5.7.19
第二次安装会安装失败 1.先停止mysql服务 service mysql stop 2.检查是否卸载干净 find / -name mysql 多用几个命令检查,不要删到其他组件的 ...
- Bootstrap--下拉菜单.dropdown
下拉菜单.dropdown .dropdown <下拉菜单触发器button+下拉菜单ul> .dropdown 包裹层 .dropdown-toggle 下拉菜单触发器 data-to ...
- Azure 基础:用 PowerShell 自动登录
PowerShell 是管理 Azure 的最好方式,因为我们可以使用脚本把很多的工作自动化.比如把 Azure 上的虚拟机关机,并在适当的时间把它开机,这样我们就能节省一些开支,当然我们同时也为减少 ...
- 运行第一个Go Web框架
GO 语言的web框架很多,相对来说, Beego 框架,入门简单,文档齐全(中文),功能强大,本文以Beego 示例. Beego提供了详细的开发文档:http://beego.me/docs/in ...
- Python多进程应用
在我之前的一篇博文中详细介绍了Python多线程的应用: 进程,线程,GIL,Python多线程,生产者消费者模型都是什么鬼 但是由于GIL的存在,使得python多线程没有充分利用CPU的多核,为 ...
- [译]ASP.NET Core 2.0 路由引擎
问题 ASP.NET Core 2.0的路由引擎是如何工作的? 答案 创建一个空项目,为Startup类添加MVC服务和请求中间件: public void ConfigureServices(ISe ...
- SE6新特性之集合Set、Map、WeakSet和WeakMap详解
SE5的时候我们经常用数组或者类数组对象来操作数据,而对于一些使用惯了java之类语言的集合的开发人员来说,总有少了点什么的感觉,SE6提供Set和Map这两个集合.不仅从根本上为一些问题提供了解决方 ...
- Increasing Speed Limits
Increasing Speed Limits Time Limit: 2000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...