用Perl寫了一些監(jiān)控腳本,放在crontab中調度執(zhí)行。有時候會發(fā)現(xiàn)一個腳本運行時間過長,會同時跑起多個實例,因此有必要為腳本加上控制,只運行一個實例。
最簡單自然的想法,在腳本中檢查并創(chuàng)建一個空的lock文件,腳本結束時再刪除。通過判斷文件是否存在的方式來判斷腳本是否已經(jīng)運行。不過這樣做有個bug,如果腳本運行過程中異常終止,lock文件沒有正常刪除,就會導致腳本無法再運行。
空的lock文件不行,那么考慮在lock文件中加入一點內容,比如進程的PID號,然后通過檢查該PID號的進程是否還在運行,就能避免上述bug了。在CPAN上有很多現(xiàn)成的模塊能夠完成上述功能,如File::Lockfile, File::Pid, Proc::PID::File 等。
下面是File::Lockfile的一個示例,非常簡單:
以下是代碼片段:
通過查看File/Lockfile.pm的源代碼可以看到,判斷l(xiāng)ock文件中記錄的進程是否已經(jīng)運行,簡單的通過 kill -0 $pid 即可實現(xiàn)。所以即使不用上述模塊,自己實現(xiàn)也是非常容易的。
小結:
該方法是在腳本中經(jīng)常用到限制單實例的方法,MySQL 等程序在每次啟動前也會檢查上次遺留的 mysql.pid 文件。
另一個方法:給lock文件加排它鎖,判斷是否有鎖來確保唯一性。