日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > PHP flock文件鎖詳解介紹

PHP flock文件鎖詳解介紹

來源:程序員人生   發布時間:2014-02-13 09:07:46 閱讀次數:2710次

為了確保操作的有效性和完整性,可以通過鎖機制將并發狀態轉換成串行狀態.作為鎖機制中的一種,PHP的文件鎖也是為了應對資源競爭.假設一個應用場景,在存在較大并發的情況下,通過fwrite向文件尾部多次有序的寫入數據,不加鎖的情況下會發生什么?多次有序的寫入操作相當于一個事務,我們此時需要保證這個事務的完整性.

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

flock() 操作的 handle 必須是一個已經打開的文件指針.operation 可以是以下值之一:

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)

建兩個文件

實例代碼如下:

(1) a.php

  1. ?$file = "temp.txt";      
  2. $fp = fopen($file , 'w');      
  3. if(flock($fp , LOCK_EX)){      
  4.      fwrite($fp , "abcn");      
  5.      sleep(10);      
  6.      fwrite($fp , "123n");      
  7.     flock($fp , LOCK_UN);      
  8. }      
  9. fclose($fp); 

(2) b.php

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

運行 a.php 后,馬上運行 b.php ,可以看到輸出:

abc

等 a.php 運行完后運行 b.php ,可以看到輸出:

abc

123

顯然,當 a.php 寫文件時數據太大,導致時間比較長時,這時 b.php 讀取數據不完整

修改 b.php 為:

實例代碼如下:

  1. ?$file = "temp.txt";      
  2. $fp = fopen($file , 'r');      
  3. if(flock($fp , LOCK_EX)){      
  4.     echo fread($fp , 100);      
  5.     flock($fp , LOCK_UN);      
  6. else{      
  7.     echo "Lock file failed...n";      
  8. }      
  9. fclose($fp);  

運行 a.php 后,馬上運行 b.php ,可以發現 b.php 會等到 a.php 運行完成后(即 10 秒后)才顯示:

abc
123

讀取數據完整,但時間過長,他要等待寫鎖釋放.修改 b.php 為:

實例代碼如下:

  1. ?$file = "temp.txt";      
  2. $fp = fopen($file , 'r');      
  3. if(flock($fp , LOCK_SH | LOCK_NB)){      
  4.     echo fread($fp , 100);      
  5.     flock($fp , LOCK_UN);      
  6. else{      
  7.     echo "Lock file failed...n";      
  8. }      
  9. fclose($fp);  

運行 a.php 后,馬上運行 b.php ,可以看到輸出:

Lock file failed…

證明可以返回鎖文件失敗狀態,而不是向上面一樣要等很久.

結論:

建議作文件緩存時,選好相關的鎖,不然可能導致讀取數據不完整,或重復寫入數據.file_get_contents 好像選擇不了鎖,不知道他默認用的什么鎖,反正和不鎖得到的輸出一樣,是不完整的數據.

我是要做文件緩存,所以只需要知道是否有寫鎖存在即可,有的話就查數據庫就可以了.多次同時執行,雖然都寫了100行,但是事務1和事務2的數據交錯寫入,這并不是我們想要的結果.我們要的是事務完整的執行,此時我們需要有個機制去保證在第一個事務執行完后再執行第二個.在PHP中,flock函數完成了這一使命.在事物1和事務2的循環前面都加上: flock($fp, LOCK_EX); 就能滿足我們的需求,將兩個事務串行.

當某一個事務執行完flock時,因為我們在這里添加的是LOCK_EX(獨占鎖定),所以所有對資源的操作都會被阻塞,只有當事務執行完成后,后面的事務才會執行.我們可以通過輸出當前的時間的方法來確認這一點.

關于在尾部追加寫入,在unix系統的早期版本中存在一個并發寫入的問題,如果要在尾部追加,需要先lseek位置,再write.當多個進程同時操作時,會因為并發導致的覆蓋寫入的問題,即兩個進程同時獲取尾部的偏移后,先后執行write操作,后面的操作會將前面的操作覆蓋.這個問題在后面以添加打開時的O_APPEND操作而得到解決,它將查找和寫入操作變成了一個原子操作.

在PHP的fopen函數的實現中,如果我們使用a參數在文件的尾部追加內容,其調用open函數中oflag參數為 O_CREAT|O_APPEND,即我們使用追加操作不用擔心并發追加寫入的問題.

在PHP的session默認存儲實現中也用到了flock文件鎖,當session開始時就調用PS_READ_FUNC,且以O_CREAT | O_RDWR | O_BINARY 打開session數據文件,此時會調用flock加上寫鎖,如果此時有其它進程訪問此文件(即同一用戶再次發起對當前文件的請求),就會顯示頁面加載中,進程被阻塞了.加寫鎖其出發點是為了保證此次會話中對session的操作事務能完整的執行,防止其它進程的干擾,保證數據的一致性.如果一個頁面沒有session修改操作,可以盡早的調用session_write_close()釋放鎖.

文件鎖是針對文件的鎖,除了這種釋義,還可以理解為用文件作為鎖.在實際工作中,有時為確保單個進程的執行,我們會在程序執行前判斷文件是否存在,如果不存在則創建一個空文件,在進程結束后刪除這個空文件,如果存在,則不執行.

但是什么時候使用lock_ex什么時候使用lock_sh呢?

讀的時候:

如果不想出現dirty數據,那么最好使用lock_sh共享鎖.可以考慮以下三種情況: 

1. 如果讀的時候沒有加共享鎖,那么其他程序要寫的話(不管這個寫是加鎖還是不加鎖)都會立即寫成功.如果正好讀了一半,然后被其他程序給寫了,那么讀的后一半就有可能跟前一半對不上(前一半是修改前的,后一半是修改后的) 

2. 如果讀的時候加上了共享鎖(因為只是讀,沒有必要使用排他鎖),這個時候,其他程序開始寫,這個寫程序沒有使用鎖,那么寫程序會直接修改這個文件,也會導致前面一樣的問題 

3. 最理想的情況是,讀的時候加鎖(lock_sh),寫的時候也進行加鎖(lock_ex),這樣寫程序會等著讀程序完成之后才進行操作,而不會出現貿然操作的情況

寫的時候:

如果多個寫程序不加鎖同時對文件進行操作,那么最后的數據有可能一部分是a程序寫的,一部分是b程序寫的。如果寫的時候加鎖了,這個時候有其他的程序來讀,那么他會讀到什么東西呢? 

1. 如果讀程序沒有申請共享鎖,那么他會讀到dirty的數據.比如寫程序要寫a,b,c三部分,寫完a,這時候讀讀到的是a,繼續寫b,這時候讀讀到的是ab,然后寫c,這時候讀到的是abc. 

2. 如果讀程序在之前申請了共享鎖,那么讀程序會等寫程序將abc寫完并釋放鎖之后才進行讀. 

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 黄色片网站免费 | 在线高潮 | 成人欧美一区二区三区视频网页 | 玖玖玖影院| 欧美一区二区视频在线 | 毛片免费在线 | a毛片在线观看 | 久久精品观看 | 国产精品久久久久永久免费观看 | 国产精品一区二 | 国产精品久久久久久亚洲调教 | 国产美女精品视频 | 香蕉久草| 久9热这里只有精品视频 | 日韩欧美综合在线视频 | 精品久久久久久久久久久久久久久久久 | julia在线播放| 久久成人综合 | 成人黄色在线播放 | 中文字幕一区二区av | av在线播放一区二区三区 | 精品久久久久久久久久岛国gif | 在线一区 | 日本天堂在线观看 | 国产精品成av人在线视午夜片 | 国产专区精品 | 正在播放av | 九九热久久这里只有精品 | 最色网| 日韩免费一区 | 91露脸的极品国产系列 | 精品国产一区二区在线 | 色丁香综合 | 久久久久久久国产精品视频 | 欧美成人综合 | 91社影院在线观看 | 亚洲欧洲无码一区二区三区 | 日本一区二区不卡视频 | 成人高清在线视频 | 久久精品视频一区 | 国产精品久久久久9999 |