qg777钱柜误乐

热门关键词: qg777钱柜误乐

php文件锁类防止并发的例子

本文实例讲述了php判断linux下程序问题。分享给大家供大家参考。具体如下:

bool flock ( int handle, int operation [, int &wouldblock] );
flock() 操作的 handle 必须是一个已经打开的文件指针。operation 可以是以下值之一:

工作间隙写了个文件锁的类,用于解决并发的一些问题。

有时候在服务器上面写一些脚本的时候,经常要放到crontab里面定时运行。时间长了就有一个问题,那就是程序重复运行消耗太多的资源,怎么处理呢?下面璞玉写了两种方法.

1.要取得共享锁定(读取程序),将 operation 设为 LOCK_SH(PHP 4.0.1 以前的版本设置为 1)
2.要取得独占锁定(写入程序),将 operation 设为 LOCK_EX(PHP 4.0.1 以前的版本中设置为 2)
3.要释放锁定(无论共享或独占),将 operation 设为 LOCK_UN(PHP 4.0.1 以前的版本中设置为 3)
4.如果你不希望 flock() 在锁定时堵塞,则给 operation 加上 LOCK_NB(PHP 4.0.1 以前的版本中设置为 4)

bool flock ( int handle, int operation [, int &wouldblock] );
flock() 操作的 handle 必须是一个已经打开的文件指针。operation 可以是以下值之一:

//第一种:用linux里面的正则匹配function ifrun{ //下面进行检测,如有一个进程正在运行,则不运行 $str=shell_exec("/bin/ps ax > /home/root/".$clsname."_run.txt"); $str=shell_exec("/bin/grep -c '".$clsname.".php' /home/root/".$clsname."_run.txt"); if { if { return 1; } else { return 0; } } else { if  { return 1; } else { return 0; } }}//调用:if { die;}//备注:pooy是程序pooy.php的名称!//第二种:把进程写到文件里面,然后用file函数去读取然后去匹配字符串system('ps -ef |grep wget > /root/pooy.txt');$arr=file;$total=count;for{ $count=array(); if(stristr !== FALSE) { //echo '"earth" not found in string'; $count[]='no'; break; }}if{ echo "A same programs are running"; exit();}else{ echo "start__________________________________________________";}//注:"www/pooy" 是程序里面包含的字符串!//现在php程序在linux运行是否通畅多了呢?

建两个文件

要取得共享锁定(读取程序),将 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

希望本文所述对大家的php程序设计有所帮助。

 代码如下

$file = "temp.txt";   
$fp = fopen($file , 'w');   
if(flock($fp , LOCK_EX)){   
     fwrite($fp , "abcn");   
     sleep(10);   
     fwrite($fp , "123n");   
    flock($fp , LOCK_UN);   
}   
fclose($fp);  
(2) b.php

(1) a.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 读取数据不完整

?$file = "temp.txt";    
$fp = fopen($file , 'w');    
if(flock($fp , LOCK_EX)){    
     fwrite($fp , "abcn");    
     sleep(10);    
     fwrite($fp , "123n");    
    flock($fp , LOCK_UN);    
}    
fclose($fp);

修改 b.php 为:

(2) 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
读取数据完整,但时间过长,他要等待写锁释放。

?$file = "temp.txt";    
$fp = fopen($file , 'r');    
echo fread($fp , 100);    
fclose($fp);

修改 b.php 为:

运行 a.php 后,马上运行 b.php ,可以看到输出:
abc
等 a.php 运行完后运行 b.php ,可以看到输出:
abc
123
显然,当 a.php 写文件时数据太大,导致时间比较长时,这时 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…
证明可以返回锁文件失败状态,而不是向上面一样要等很久。

修改 b.php 为:

结论:
建议作文件缓存时,选好相关的锁,不然可能导致读取数据不完整,或重复写入数据。
file_get_contents 好像选择不了锁,不知道他默认用的什么锁,反正和不锁得到的输出一样,是不完整的数据。
我是要做文件缓存,所以只需要知道是否有写锁存在即可,有的话就查数据库就可以了。
测试环境:Linux(Ubuntu 6) , PHP 5.1.2 , Apache 2

本文由qg777发布于编程,转载请注明出处:php文件锁类防止并发的例子

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。