2010-08-25 130 views
6

我有一個php腳本,需要每5分鐘運行一次。目前我使用的是一個cron作業來運行它(並且效果很好),但我的主機只允許15分鐘的最短時間。每5分鐘運行一次PHP腳本並避免競爭條件

所以我的問題是,我可以使用訪客觸發每5分鐘運行一個PHP腳本。我可以很容易地記錄它上次運行的時間,並根據經過的時間重新運行它。

但是,我很擔心競賽條件。劇本每5分鐘一次只能運行一次,這一點很重要。

我的腳本需要大約60秒才能運行。它在這段時間寫入一對夫婦的文件。如果腳本運行多次,將會損壞文件。另外,如果我在10分鐘內沒有獲得訪問者,那麼當下一個訪問者到達時運行一次就沒有問題。

是否有一些標準的方法來完成這項任務?

謝謝!

+0

我不確定我是否理解這個問題。是否您的主機不允許cron作業比每15分鐘更頻繁地執行? – Icode4food 2010-08-25 23:57:32

+1

標準的方式是使用一個web主機,它不會對cron施加任何壞的,任意的規則。誰這麼做? – Erik 2010-08-26 00:30:56

+1

切換主機。解決問題 – Stoosh 2010-08-26 00:31:55

回答

6

你有沒有考慮過讓你的腳本運行一個無限循環與sleep在迭代之間等待5分鐘?

for (;;) 
{ 
    perform_actions(); 
    sleep(300); 
} 

或者,你可以有一個文件(例如,is_running),與其上月底公佈你的腳本開始得到它的獨家lock。至少這樣你不會做任何破壞性的事情。

你也可以結合這兩個解決方案。

$fp = fopen("is_running", "r+"); 

/* is it already running? */ 
if (! flock($fp, LOCK_EX | LOCK_NB)) return; 

for (;;) 
{ 
    perform_actions(); 
    sleep(300); 
} 

然後讓cron作業每15分鐘運行一次。如果這個過程仍在運行,它將只是保釋出來,否則它會重新啓動並每5分鐘恢復一次更新。

+0

這似乎是一個好主意和一個相當不錯的解決方案。我猜我需要調用php的set_time_limit。然後我希望我的主機不會自動殺死長時間運行的進程...但是,這似乎是我最好的選擇。謝謝。 – Imbue 2010-08-26 01:16:39

+1

'set_time_limit'是您需要調整超時的功能。 http://php.net/manual/en/function.set-time-limit.php每次腳本運行時,我都會將它設置爲330,這樣你就不用擔心了。 – Icode4food 2010-08-26 01:39:08

+1

爲了讓你們知道,主機允許我的腳本運行約。殺死它前26小時。不久之後,cron彈出另一個注意到文件已解鎖並且我又恢復正常工作的文件。有一件事會嚇倒我,如果主機在寫入數據時殺死我的腳本,會發生什麼情況。在這種情況下,數據可能會被破壞,直到cron有機會運行另一個腳本。換句話說,一年幾次,我可能會服務大約5-10分鐘的損壞數據。 – Imbue 2010-08-28 21:03:54

1

如果你不能做@Brandon提出的建議,我會推薦這樣做,就像我在PHP編寫守護進程時所做的一樣(不是最好的解決方案,但我實際上被迫這樣做)。

在我的例子中,腳本訪問了一個(日誌)文件並對它進行了處理,之後將結果插入到數據庫中。所以爲了確保我沒有同時運行兩個文件,我創建了一個「狀態」文件,腳本在該文件上獲取了一個鎖,如果不能正常運行,就不能這樣做。

$fh = fopen('status_file', 'w'); 

/** 
* LOCK_NB is required because otherwise your script would stall until 
* a lock is aquired, queing a bunch of scripts. 
*/ 
if(!flock($fh, LOCK_EX | LOCK_NB)) { 
    exit 1; // our job is done here 
} 
4

跛腳回答跛腳的情況(ISP,而不是海報)。 Schedule 12 cron作業,全部調用相同的腳本,每個腳本每小時運行一次,但調用的時間不同於5分鐘。

00 * * * * root echo "run at :00 of every hour" 
05 * * * * root echo "run at :05 of every hour" 
10 * * * * root echo "run at :10 of every hour" 

等到:55。但我支持我的原始評論 - 找到一個新的ISP :)

+1

我相信這會起作用,這可能是一個體面的解決方案,但我擔心如果我的主機注意到它會發生什麼。 – Imbue 2010-08-26 01:14:03

+3

@Imbue - 所以你認爲你的主人會在無限循環中看起來更加善良? – 2010-08-26 01:36:50

+0

我認爲一個花費在睡眠中幾乎所有時間的無限循環將不那麼明顯,也許有點反抗。或不。很難說真的。 – Imbue 2010-08-26 02:32:53

0

您可以使用The Fat Controller以5分鐘的間隔運行腳本。與CRON不同,它保證從腳本的一個實例結束到另一個啓動時的時間間隔。

+0

嗨我發送了一條評論在您的網站上詢問有關TheFatController的事情,我的名字是'geocine' – 2011-07-04 16:54:31

0

訪問者是否可以啓動此腳本的答案是肯定的。當訪問者進入頁面時,您可以運行該腳本。您需要存儲開始時間,但也需要存儲它是否正在運行的屬性。這應該避免在嘗試更新數據時出現任何衝突的可能性。如果運行時間超過最大時間,則可以使用額外的郵件警告字段。然後您可以讓腳本向您發送警告電子郵件,說明您的腳本已超出最大時間。我親自將這些狀態保存在數據庫中,但它們也可以存儲在文件中。