只想知道 发表于 2015-1-16 22:12:07

PHP教程之怎样办理php中并发读写文件抵触的成绩

总的来说,在这一个月左右的时间中,学到的不少,但是也遇到不少的问题,比如批量图片的上传,一直到现在也不懂,如何实现动态的增加上传图片的数量。关于日IP不高大概说并发数不是很年夜的使用,一样平常不必思索这些!用一样平常的文件操纵办法完整没有成绩。但假如并发高,在我们对文件举行读写操纵时,很有大概多个历程对进一文件举行操纵,假如这时候不合错误文件的会见举行响应的独有,就简单形成数据丧失。
比方:一个在线谈天室(这里假定把谈天内容写进文件),在统一时候,用户A和用户B都要操纵数据保留文件,起首是A翻开了文件,然后更新内里的数据,但这里B也恰好也翻开了统一个文件,也筹办更新内里的数据。当A把写好的文件保留时,这里实在B已翻开了文件。但当B再把文件保留归去时,这里已形成了数据的丧失,由于这里B用户完整不晓得它所翻开的文件在它对其举行变动时,A用户也变动了这个文件,以是最初B用户保留变动时,用户A的更新就被会丧失。
关于如许的成绩,一样平常的办理计划时当一历程对文件举行操纵时,起首对别的举行加锁,意味着这里只要该历程有权对文件举行读取,别的历程假如如今读,是完整没有成绩,但假如这时候有历程试图想对其举行更新,会遭到操纵回绝,先前对文件举行加锁的历程这时候假如对文件的更新操纵终了,这就开释独有的标识,这时候文件又恢复到了可变动的形态。接上去同理,假如谁人历程在操纵文件时,文件没有加锁,这时候,它就能够宁神勇敢的对文件举行锁定,单独享用。
以是一样平常的计划会是:
$fp=fopen(/tmp/lock.txt,w+);if(flock($fp,LOCK_EX)){fwrite($fp,"Writesomethinghere
");flock($fp,LOCK_UN);}else{echoCouldn        lockthefile!;}fclose($fp);但在PHP中,flock仿佛事情的不是那末好!在多并发情形下,仿佛是常常独有资本,不立即开释,大概是基本不开释,形成逝世锁,从而使服务器的cpu占用很高,乃至偶然候会让服务器完全逝世失落。仿佛在良多linux/unix体系中,城市有如许的情形产生。以是利用flock之前,必定要稳重思索。
那末就没有办理计划了吗?实在也不是如许的。假如flock()我们利用妥当,完整大概办理逝世锁的成绩。固然假如不思索利用flock()函数,也一样会有很好的办理计划来办理我们的成绩。经由我团体的汇集和总结,大抵归结懂得决计划有以下几种。
计划一:对文件举行加锁时,设置一个超不时间。大抵完成以下:
if($fp=fopen($fileName,a)){$startTime=microtime();do{$canWrite=flock($fp,LOCK_EX);if(!$canWrite){usleep(round(rand(0,100)*1000));}}while((!$canWrite)&&((microtime()-$startTime)<1000));if($canWrite){fwrite($fp,$dataToSave);}fclose($fp);}超时设置为1ms,假如这里工夫内没有取得锁,就重复取得,间接取得到对文件操纵权为止,固然。假如超时限定已到,就必须即刻加入,让出锁让别的历程来举行操纵。
计划二:不利用flock函数,借用一时文件来办理读写抵触的成绩。大抵道理以下:
(1)将必要更新的文件思索一份到我们的一时文件目次,将文件最初修正工夫保留到一个变量,并为这个一时文件取一个随机的,不简单反复的文件名。
(2)当对这个一时文件举行更新后,再检测原文件的最初更新工夫和先前所保留的工夫是不是分歧。
(3)假如最初一次修正工夫分歧,就将所修正的一时文件重定名到原文件,为了确保文件形态同步更新,以是必要扫除一下文件形态。
(4)可是,假如最初一次修正工夫和先前所保留的分歧,这申明在这时代,原文件已被修正过,这时候,必要把一时文件删除,然后前往false,申明文件这时候有别的历程在举行操纵。
大抵完成代码以下:
$dir_fileopen=tmp;functionrandomid(){returntime().substr(md5(microtime()),0,rand(5,12));}functioncfopen($filename,$mode){global$dir_fileopen;clearstatcache();do{$id=md5(randomid(rand(),TRUE));$tempfilename=$dir_fileopen./.$id.md5($filename);}while(file_exists($tempfilename));if(file_exists($filename)){$newfile=false;copy($filename,$tempfilename);}else{$newfile=true;}$fp=fopen($tempfilename,$mode);return$fp?array($fp,$filename,$id,@filemtime($filename)):false;}functioncfwrite($fp,$string){returnfwrite($fp,$string);}functioncfclose($fp,$debug=off){global$dir_fileopen;$success=fclose($fp);clearstatcache();$tempfilename=$dir_fileopen./.$fp.md5($fp);if((@filemtime($fp)==$fp)($fp==true&&!file_exists($fp))$fp==true){rename($tempfilename,$fp);}else{unlink($tempfilename);//申明有别的历程在操纵方针文件,以后历程被回绝$success=false;}return$success;}$fp=cfopen(lock.txt,a+);cfwrite($fp,"welcometobeijing.
");fclose($fp,on);关于下面的代码所利用的函数,必要申明一下:
(1)rename();重定名一个文件或一个目次,该函数实在更像linux里的mv。更新文件大概目次的路径或名字很便利。但当我在window测试下面代码时,假如新文件名已存在,会给出一个notice,说以后文件已存在。但在linux下事情的很好。
(2)clearstatcache();扫除文件的形态.php将缓存一切文件属性信息,以供应更高的功能,但偶然,多历程在对文件举行删除大概更新操纵时,php没来得及更新缓存里的文件属性,简单招致会见到最初更新工夫不是实在的数据。以是这里必要利用该函数对已保留的缓存举行扫除。
计划三:对操纵的文件举行随机读写,以下降并发的大概性。
在对用户会见日记举行纪录时,这类计划仿佛被接纳的对照多。先前必要界说一个随机空间,空间越年夜,并发的的大概性就越小,这里假定随机读写空间为,那末我们的日记文件的散布就为log1~到log500不等。每次用户会见,都将数据随机写到log1~log500之间的任一文件。在统一时候,有2个历程举行纪录日记,A历程多是更新的log32文件,而B历程呢?则此时更新的大概就为log399.要晓得,假如要让B历程也操纵log32,几率基础上为1/500,差未几约即是零。在必要对会见日记举行剖析时,这里我们只必要先将这些日记兼并,再举行剖析便可。利用这类计划来纪录日记的一个优点时,历程操纵列队的大概性对照小,可使历程很敏捷的完成每次操纵。
计划四:将一切要操纵的历程放进一个行列中。然后专门放一个服务完成文件操纵。行列中的每个扫除的历程相称于第一个详细的操纵,以是第一次我们的服务只必要从行列中获得相称于详细操纵事项就能够了,假如这里另有大批的文件操纵历程,不妨,排到我们的行列前面便可,只需乐意排,行列的多长都不妨。
关于之前几种计划,各有各的优点!大抵大概归结为两类:
(1)必要列队(影响慢)好比计划1、2、四
(2)不必要列队。(影响快)计划三
在计划缓存体系时,一样平常我们不会接纳计划三。由于计划三的剖析程序和写进程序是分歧步的,在写的工夫,完整不思索到时分剖析的难度,尽管写的行了。试想一下,如我们在更新一个缓存时,假如也接纳随机文件读写法,那末在读缓存时仿佛会增添良多流程。但接纳计划1、二就完整纷歧样,固然写的工夫必要守候(当猎取锁不乐成时,会重复猎取),但读文件是很便利的。增加缓存的目标就是要削减数据读取瓶颈,从而进步体系功能。
从上为团体履历和一些材料的总结,有甚么不合错误的中央,大概没有谈到的中央,接待列位偕行斧正。
您大概感乐趣的文章


[*]利用PHP的GZip紧缩功效对网站JS和CSS文件举行紧缩减速网站会见速率
[*]php中关于笼统(abstract)类和笼统办法的成绩剖析
[*]php怎样扫除html格局并往除笔墨中的空格然后截取笔墨
[*]php清空(删除)指定目次下的文件,不删除目次文件夹的办法
[*]php猎取目次一切文件并将了局保留到数组的程序
[*]PHP对变量举行序列化的办法年夜比拼php四种序列化变量的办法
[*]用PHP函数memory_get_usage猎取以后PHP内存损耗量以完成程序的功能优化
[*]phperror_log()将毛病信息写进一个文件
既然选择了PHP,就要坚持学下去!大家有没有问自己为什么会选择学习PHP呢?就我个人而言,完全是因为兴趣,因为我的专业和计算机完全无关,但是就是对编程很赶兴趣,尤其对网络编程、web开发特别赶兴趣。

透明 发表于 2015-1-17 17:51:17

最后介绍一个代码出错,但是老找不到错误方法,就是gotowc(囧),出去换换气没准回来就找到错误啦。

兰色精灵 发表于 2015-1-21 06:08:10

多看优秀程序员编写的代码,仔细理解他们解决问题的方法,对自身有很大的帮助。

第二个灵魂 发表于 2015-1-30 09:24:49

使用 jquery 等js框架的时候,要随时注意浏览器的更新情况,不然很容易发生框架不能使用。

分手快乐 发表于 2015-2-6 09:36:36

小鸟是第一次发帖(我习惯潜水的(*^__^*) 嘻嘻……),有错误之处还请大家批评指正,另外,前些日子听人说有高手能用php写驱动程序,真是学无止境,人外有人,天外有天。

若相依 发表于 2015-2-15 22:08:12

先学习php和mysql,还有css(html语言很简单)我认为现在的效果比以前的方法好。

金色的骷髅 发表于 2015-3-4 15:17:25

对于懒惰的朋友,我推荐php的集成环境xampp或者是wamp。这两个软件安装方便,使用简单。但是我还是强烈建议自己动手搭建开发环境。

飘飘悠悠 发表于 2015-3-11 20:20:01

如果你可以写完像留言板这样的程序,那么你可以去一些别人的代码了,

乐观 发表于 2015-3-19 11:59:24

微软最近出的新字体“微软雅黑”,虽然是挺漂亮的,不过firefox支持的不是很好,所以能少用还是少用的好。

简单生活 发表于 2015-3-28 01:36:04

小鸟是第一次发帖(我习惯潜水的(*^__^*) 嘻嘻……),有错误之处还请大家批评指正,另外,前些日子听人说有高手能用php写驱动程序,真是学无止境,人外有人,天外有天。
页: [1]
查看完整版本: PHP教程之怎样办理php中并发读写文件抵触的成绩