天天看點

crond中使用flock指令的坑

需要定期去執行一個php腳本,首先想到的是通過crond指令來實作這個功能。但是,在crond的執行過程中發現一個詭異的事情。在crond中的配置如下。

腳本隻會在第一次成功執行,之後就不會再執行。當删除/tmp/test.lock檔案後,php腳本又能正常執行了。執行完一次後,就又不能正常執行了。

把crond配置中把flock去掉。如下:

發現腳本可以正常執行了。那必定是flock的問題。flock作為一個成熟的linux指令,有問題的可能性不大。最大的可能性就是php代碼中某部分代碼和flock沖突。php代碼如下:

之前說過,隻有第一次,flock的鎖檔案不存在的時候,才能正常執行。當鎖檔案存在後,就不再正常執行。php程式執行完畢後,flock并沒有釋檔案鎖。那我們看下,/tmp/test.lock檔案是被那個檔案所占用。

可見,test.lock檔案正是被php程式中popen函數啟動的程序所占用。由于,啟動的是一個守護程序,程序不退出,鎖一直被占用。

linux系統上的檔案鎖主要分為協同鎖(advisory lock)和強制鎖(mandatory lock)。在linux上使用的檔案鎖大部分為協同鎖,而且使用強制鎖的時候也要檢查系統是否支援強制鎖.

協同鎖,是使用者程序主動申請檔案鎖,鎖才能起作用。比如,a程序已經對檔案加了協同鎖,如果b程序不去申請鎖,而直接對檔案進行寫操作,也是可以的。

強制鎖,是由作業系統核心保證的。不需要使用者程序自己去申請。

flock指令使用的就是協同鎖。

當一個主程序擷取一個檔案鎖後,fork出的子程序也會擷取這個檔案鎖。