makdir php 并发报错_PHP并发读写文件如何解决 - microtime

关于microtime()函数的问题我分别在程序的开头和结尾用microtime()函数取得当前时间,然后相减得到程序运行时间,在5.2版本的php上没问题,但是在5.3、5.4和5.5三个版本的php相减结果不是0就是0.0156,跟5.2.6版本的完全不同,这是...

在并发高的情况下,操作同一个文件会导致数据错乱,所以需要在操作文件时进行一些特殊处理,下面总结一下几种解决方案。希望能帮助到大家。

方案一:使用flock函数对文件加锁/*

* flock(file,lock,block)

* file 必需,规定要锁定或释放的已打开的文件

* lock 必需。规定要使用哪种锁定类型。

* block 可选。若设置为 1 或 true,则当进行锁定时阻挡其他进程。

* lock

* LOCK_SH 要取得共享锁定(读取的程序)

* LOCK_EX 要取得独占锁定(写入的程序)

* LOCK_UN 要释放锁定(无论共享或独占)

* LOCK_NB 如果不希望 flock() 在锁定时堵塞

/*

// 获取锁if (flock($file,LOCK_EX)) { // 操作文件

fwrite($file,'write more words');

// 操作完毕后释放锁

flock($file,LOCK_UN);

} else {

//处理错误逻辑

}

fclose($file);

flock函数在多并发情况下,似乎会经常独占资源,不即时释放,或者是根本不释放,造成死锁,从而使服务器的cpu占用很高,甚至有时候会让服务器彻底死掉。所以单纯的使用flock加锁并不能完全解决问题。

方案二:限定加锁时间,超时则退出if($fp = fopen($fileName,'a')) { $startTime = microtime(); do{ $canWrite = flock($fp, LOCK_EX); if(!$canWrite) {

usleep(round(rand(0, 100) * 1000)); // 释放cpu,将cpu资源先让给其他进程

} // 如果未获取到锁,且未超时,则继续获取锁

} while((!$canWrite) && ((microtime() - $startTime) < 1000)); if($canWrite) { fwrite($fp, $dataToSave);

flock($file,LOCK_UN);

} fclose($fp);

}

方案三:使用临时文件$dir_fileopen='tmp';function cfopen($filename,$mode){

global $dir_fileopen;

clearstatcache(); // 创建一个临时文件

do{ $id=uniqid(); $tempfilename=$dir_fileopen.'/'.$id.md5($filename);

} while(file_exists($tempfilename)); // 将要操作的文件内容拷贝到临时文件中

copy($filename,$tempfilename); $fp = fopen($tempfilename, $mode); return $fp ? [$fp, $filename, $id, @filemtime($filename)] : false;

}function cfwrite($fp,$string){

// 将新增内容写入到临时文件中

return fwrite($fp[0], $string);

}function cfclose($fp){

global $dir_fileopen; $success = fclose($fp[0]);

clearstatcache(); $tempfilename = $dir_fileopen.'/'.$fp[2].md5($fp[1]); // 如果要操作的文件在操作期间没有被修改过,则说明没有人操作过该文件,那么将临时文件改名为真正的文件

if((@filemtime($fp[1]) == $fp[3])){

rename($tempfilename,$fp[1]);

}else{ //说明有其它进程在操作目标文件,当前进程被拒绝,删除临时文件

unlink($tempfilename); $success = false;

} return $success;

}$startTime = microtime();do{ $fp=cfopen('lock.txt','a+');

cfwrite($fp,"welcome to beijing.\n"); $success = cfclose($fp, 'on'); if(!$success) {

usleep(round(rand(0, 100) * 1000)); // 释放cpu,将cpu资源先让给其他进程

}

}while(!$success && ((microtime() - $startTime) < 1000)); // 如果为false,说明操作失败,则重新进行一次操作

方案四:使用队列

创建一个文件操作的队列,然后写一个脚本从队列中依次读取文件操作的信息再对文件进行相应的操作,这样每次就只有一个进程在操作文件,就解决了并发的问题。

以上内容参考自:http://blog.csdn.net/daiyan_csdn/article/details/51524781

在并发高的情况下,操作同一个文件会导致数据错乱,所以需要在操作文件时进行一些特殊处理,下面总结一下几种解决方案。

方案一:使用flock函数对文件加锁/*

* flock(file,lock,block)

* file 必需,规定要锁定或释放的已打开的文件

* lock 必需。规定要使用哪种锁定类型。

* block 可选。若设置为 1 或 true,则当进行锁定时阻挡其他进程。

* lock

* LOCK_SH 要取得共享锁定(读取的程序)

* LOCK_EX 要取得独占锁定(写入的程序)

* LOCK_UN 要释放锁定(无论共享或独占)

* LOCK_NB 如果不希望 flock() 在锁定时堵塞

/*

// 获取锁if (flock($file,LOCK_EX)) { // 操作文件

fwrite($file,'write more words');

// 操作完毕后释放锁

flock($file,LOCK_UN);

} else {

//处理错误逻辑

}

fclose($file);

flock函数在多并发情况下,似乎会经常独占资源,不即时释放,或者是根本不释放,造成死锁,从而使服务器的cpu占用很高,甚至有时候会让服务器彻底死掉。所以单纯的使用flock加锁并不能完全解决问题。

方案二:限定加锁时间,超时则退出if($fp = fopen($fileName,'a')) { $startTime = microtime(); do{ $canWrite = flock($fp, LOCK_EX); if(!$canWrite) {

usleep(round(rand(0, 100) * 1000)); // 释放cpu,将cpu资源先让给其他进程

} // 如果未获取到锁,且未超时,则继续获取锁

} while((!$canWrite) && ((microtime() - $startTime) < 1000)); if($canWrite) { fwrite($fp, $dataToSave);

flock($file,LOCK_UN);

} fclose($fp);

}

方案三:使用临时文件$dir_fileopen='tmp';function cfopen($filename,$mode){

global $dir_fileopen;

clearstatcache(); // 创建一个临时文件

do{ $id=uniqid(); $tempfilename=$dir_fileopen.'/'.$id.md5($filename);

} while(file_exists($tempfilename)); // 将要操作的文件内容拷贝到临时文件中

copy($filename,$tempfilename); $fp = fopen($tempfilename, $mode); return $fp ? [$fp, $filename, $id, @filemtime($filename)] : false;

}function cfwrite($fp,$string){

// 将新增内容写入到临时文件中

return fwrite($fp[0], $string);

}function cfclose($fp){

global $dir_fileopen; $success = fclose($fp[0]);

clearstatcache(); $tempfilename = $dir_fileopen.'/'.$fp[2].md5($fp[1]); // 如果要操作的文件在操作期间没有被修改过,则说明没有人操作过该文件,那么将临时文件改名为真正的文件

if((@filemtime($fp[1]) == $fp[3])){

rename($tempfilename,$fp[1]);

}else{ //说明有其它进程在操作目标文件,当前进程被拒绝,删除临时文件

unlink($tempfilename); $success = false;

} return $success;

}$startTime = microtime();do{ $fp=cfopen('lock.txt','a+');

cfwrite($fp,"welcome to beijing.\n"); $success = cfclose($fp, 'on'); if(!$success) {

usleep(round(rand(0, 100) * 1000)); // 释放cpu,将cpu资源先让给其他进程

}

}while(!$success && ((microtime() - $startTime) < 1000)); // 如果为false,说明操作失败,则重新进行一次操作

方案四:使用队列

创建一个文件操作的队列,然后写一个脚本从队列中依次读取文件操作的信息再对文件进行相应的操作,这样每次就只有一个进程在操作文件,就解决了并发的问题。

相关推荐:

解决php并发读写文件冲突的问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值