2012-03-01 70 views
1

我想確保一次只能運行一個perl腳本的一個實例。該腳本根據傳入的參數執行某種類型的db_operation。該腳本不一定位於一個地方或一臺機器上,也可能位於多個OS中。雖然文件系統在各種機器上自動安裝。Muetexes in perl&MySQL

我的第一個形式給出是隻創建一個.lock文件,並執行以下操作:

use warnings; 
use strict; 
use Fcntl qw(:DEFAULT :flock); 
... 
open(FILE,">>",$lockFilePath); 
flock(FILE,LOCK_EX) or die("Could not lock "); 
do_something(); 
flock(FILE,LOCK_UN) or die("Could not unlock "); 
close(FILE); 

,但我不斷收到以下錯誤:

Bareword "LOCK_EX" not allowed while "strict subs" in use 
Bareword "LOCK_UN" not allowed while "strict subs" in use 

所以我要尋找另一種方式來解決這個問題。鎖定數據庫本身也是不現實的,因爲數據庫可以被其他腳本使用(這是可以接受的),我只是試圖阻止這個腳本運行。並且鎖定一個表格是不實際的,因爲我的腳本不知道該操作發生在哪個表上,它只是啓動另一個作爲參數提供的perl腳本。

我正在考慮向db中添加一個表,只有一個值,並將其用作muetex,但我不知道這是多麼的實用/可靠(我的很多紅旗都在頭)。我有一個到這個腳本使用的db的DBI連接。

謝謝

+0

聽起來像你的子腳本需要做自己的鎖定,因爲你的跑步者腳本不知道是否安全地運行多個副本。 – 2012-03-01 15:13:47

+0

很奇怪,你會得到那個錯誤。確保'使用Fcntl qw(:flock);'對你使用它的塊有效。嘗試直接在'flock'調用之上添加它。你也可以嘗試使用這些常量的值,參見[flock](http://perldoc.perl.org/functions/flock.html)。 – Qtax 2012-03-01 15:31:11

回答

5

您聽到的Bareword錯誤聽起來像是您在「...」中做了一些事情來混淆Perl關於導入的Fcntl常量。使用那些常量是沒有問題的。你可以嘗試像LOCK_UN()這樣的東西來看看你會得到什麼樣的錯誤。

如果您使用MySQL,您可以使用GET_LOCK()RELEASE_LOCK()機制。它的工作原理相當不錯了這樣的情況:

SELECT GET_LOCK("script_lock"); 

,然後當你完成:

SELECT RELEASE_LOCK("script_lock"); 

詳見http://dev.mysql.com/doc/refman/4.1/en/miscellaneous-functions.html

+0

謝謝,這似乎是工作 – Smartelf 2012-03-01 16:03:17

+0

或'&LOCK_EX','&LOCK_UN'等。 – mob 2012-03-01 16:05:23

1

您可能想要避免文件鎖定;從我記得在非本地文件系統中出現的臭名昭着的不可靠。最好的辦法是僅僅使用文件本身的存在來指示腳本已經在運行(類似於UNIX的PID文件)。當然,這不是100%可靠的,但是應該在非常低的開銷下合理可靠地工作,前提是腳本不會被不斷調用。

如果您需要更好的可靠性,使用互斥數據庫是一個很好的解決方案。