1. 程式人生 > >php檔案鎖解析

php檔案鎖解析

php檔案鎖

bool flock() ( int handle, int operation [, int &wouldblock] );

    flock() 操作的handle 必須是一個已經開啟的檔案指標。operation 可以是一下值中的一個:

1. 要取得共享鎖(讀取程式),將operation 設為 LOCK_SH (php4.0.1以前的版本設定為1)
2. 要取得獨佔鎖(寫入程式),將operation 設為 LOCK_XH (php4.0.1以前的版本設定為2)
3. 要釋放鎖定(無論共享或獨佔),將operation 設為 LOCK_UN (php4.0.1以前的版本設定為3)
4. 如果你不希望flock()在鎖定是堵塞,將operation 設為 LOCK_NB(php4.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); 
  1. 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 好像選擇不了鎖,不知道他用的什麼鎖,和不加鎖時得到的結果是一樣的,資料不完整。

檔案鎖有兩種:共享鎖(LOCK_SH)和排它鎖(LOCK_XH),也就是讀鎖和寫鎖。
檔案鎖一般這麼使用:

$fp = fopen("filename", "a");   
flock($fp, LOCK_SH) or die("lock error")   
$str = fread($fp, 1024);   
flock($fp, LOCK_UN);   
fclose($fp); 

fwrite()之後檔案立即就被更新了,而不是等到fclose()之後。

讀的時候:
如果不想出現dirty資料,最好使用LOCK_SH共享鎖。可以考慮一下三種情況:
1. 如果讀的時候沒有加共享鎖,那麼其他程式寫的話(不管這個寫加鎖還是不加鎖)都會立即寫成功。如果正好讀了一半,然後被其他程式給寫了,那麼讀的後一半就可能跟前一半對不上(前一半是修改前的,後一半是修改後的)
2. 如果讀的時候加上了共享鎖(因為只是讀,沒必要加排它鎖),這個時候其他程式開始寫,這個寫程式沒有使用鎖,那麼寫程式會直接修改這個檔案,也會導致前面一樣的問題。
3. 最理想的情況是,讀的時候加鎖(LOCK_SH),寫的時候也加鎖(LOCK_XH),這樣寫程式會等著讀程式完成之後才進行操作,而不會出現貿然操作的情況。
寫的時候:
如果多個寫程式不加鎖同時對檔案進行操作,那麼最後的資料可能一部分是a程式寫的,一部分是b程式寫的。
如果寫的時候加鎖了,這個時候有其他的程式來讀,那麼他會讀到什麼東西呢?
1. 如果讀程式沒有申請共享鎖,那麼他會讀到dirty資料。比如寫程式要寫a,b,c三部分,寫完a,這時候讀到的是a,繼續寫b,這時候讀到的是ab,然後寫c,這時候讀到的是abc
2. 如果讀程式之前申請了共享鎖,那麼讀程式會等寫程式將abc寫完並釋放鎖之後才進行讀。

相關推薦

PHP檔案解析 flock()

1、普通寫入和讀取b.php寫入$file = 'tt.txt';$fp = fopen($file,'a+b');fwrite($fp,"c");sleep(3);fwrite($fp,"a");c.php讀取$file = 'tt.txt';$fp = fopen($f

php檔案解析

php檔案鎖 bool flock() ( int handle, int operation [, int &wouldblock] ); flock() 操作的handle 必須是一個已經開啟的檔案指標。operation 可以是一下值

MySQL(表)、PHP(檔案)機制及應用場景

模擬高併發訪問一個指令碼:apache安裝檔案的bin/ab.exe可以模擬併發量 C:\phpStudy\Apache\bin>ab.exe -c 10 -n 10 http://localhost/try.php // -c 模擬多少併發量 -n 一共請求多少次 http://請求的指令

PHP檔案

一、檔案鎖是什麼 ?         顧名思義,對檔案上鎖。         可以通過“進門”的實際情況來理解:         有多個人要通過一個大門到食堂裡吃飯,但食堂只有一個座位,食堂管理員A不希望讓人坐地上吃飯,所以就通知大家在門外排隊,一個人進來吃完後,下一個

php檔案:共享和排他的理解

檔案鎖有兩種:共享鎖和排他鎖,也就是讀鎖(LOCK_SH)和寫鎖(LOCK_EX)   檔案的鎖一般這麼使用:   $fp = fopen("filename", "a");   flock($fp, LOCK_SH) or die("lock error")   $str

PHP 利用檔案處理高併發

利用 flock()函式對檔案進行加鎖(排它鎖),實現併發按序進行。 flock(file,lock,block)有三個引數。 file : 已經開啟的檔案 lock : 鎖的型別 LOCK_SH : 共享鎖定(讀鎖) LOCK_EX : 獨佔鎖定(排它鎖,寫鎖

apache無法解析php檔案,顯示php原始碼或直接下載檔案

我百度了一下午,根本原因是漏了一個php擴充套件:mod_php 安裝完重啟apache就好了。 yum install mod_php 其他解決辦法 羅列一下百度搜到的一些其他解決辦法,本人嘗試無用。   1.找到: AddType application/x

PHP檔案寫在哪裡,如何訪問才能解析

PHP 超文字前處理器(動態生成Html) 一.PHP檔案寫在哪裡,如何訪問才能解析 1.字尾名必須為.php  編輯器開啟 2.<?php ?>  php語法 3.放在此目錄下   D:\xampp\htdocs 4.開啟Apache服

PHP session、併發、覆蓋問題解析

本文分享PHP的session在使用過程中的鎖和併發的問題,與之相關的現象有請求阻塞、session資料丟失、session資料讀不到。 我登入不了了 某天,我準備登入我們一個後臺系統,前去解決一個bug,在賬戶密碼驗證碼都準確輸入的情況下,我登入不上,經過多次實驗發現主要有兩個錯誤資訊: csrf驗證

php檔案進行加、解

        在專案中,一般都用到日誌,如資料庫查詢日誌、訪問日誌、對外介面請求返回引數日誌,在處理日誌時簡單的寫法如下 $file = 'log.txt'; $fp = fopen($file, 'a+'); if(!is_writable($file)){

apache無法解析php檔案顯示原始碼

在httpd.conf中新增以下程式碼即可,     AddHandler  php5-script     php     AddType     application/x-httpd-php        .php .php5     AddType     appl

搭建LNMP,可以解析PHP檔案

一、安裝 nginx 1. yum -y install pcre-devel zlib-devel links  下載相應軟體 可以使用rpm -qa 軟體名 來檢視是否安裝成功?? 2.useradd -u 250  -M -s /sbin/nologi

Nginx與Apache解析php檔案的區別

一、Apache是如何解析php檔案的 我們常說的lamp架構是linux、apache、mysql、php,我們知道任何架構或者網站離不開資料庫的支援,那麼php和apache又是如何協同工作的呢? php是apache的一個外掛程式,必須依靠web伺服器才可以執行

LNMP環境問題--nginx不解析php檔案

php、nginx都裝完了,配置了好長時間都不對。剛整好。 nginx.conf 開始是 server { listen 8080; ser

Linux下Apache無法解析.php檔案

    解決辦法:     修改Apache的配置檔案:httpd.conf 通過增加引數模組,讓 Apache 將副檔名 .php 解析成 PHP。為了避免潛在的危險,例如上傳或者建立類似exploit.php.jpg的檔案並被當做 PHP 執行,我們不再使用 Apach

nginx 配置PHP fastcgi無法解析問題

配置 nginx php 很多朋友在初次接觸nginx,配置php-fpm時都會遇到無法解析index.php頁面的情況,搞得煩躁不安,心想明明是按著官方文檔來的為什麽會出現這種情況?通常我們都會如下配置:location ~ \.php$ { root /usr/share/

LAMP架構(PHP的安裝解析

php安裝編譯 ng、apa、sql和php的編譯參數 mysqli mysqlnd pdo PHP官網www.php.net當前主流版本為5.6/7.1一,下載php包: wget http://cn2.php.net/distributions/php-****.tar.gz二,解壓php包:

IIS支持PHP文件解析

OS module spl isp 模塊 nbsp bsp splay 名稱 打開IIS程序映射 添加模塊映射 請求路徑為:*.php 模塊為:FastCgiModule 可執行路徑選擇 php-cgi.exe 名稱隨意寫 IIS支持PHP文件解析

php使用SimpleXML解析xml文檔將其轉化為數組

常熟 oot foreach 三國 json lex mxml roo type XML 的設計宗旨是傳輸數據,而非顯示數據。因為需要讀取其中數據。我們通常對數組的操作非常熟悉我們可將xml解析完當成數組處理。 <?xml version="1.0" encoding

httpd中使用php模塊解析php網頁

下使用 關聯 servers 配置參數 筆記本 .gz uri hat gist 在httpd配置文件中添加php解析 修改apache的配置文件,讓apache可以使用php進行解析httpd的配置文件在/usr/local/httpd/conf/httpd.conf路徑