2013-07-26 55 views
3

我想運行在後臺PHP腳本和它的PID存儲在數據庫中。這樣我就可以檢查特定的腳本是否運行(稍後)。PHP進程ID和獨特

我們可以使用getmypid來獲得當前的PID。

但是作爲每PHP手冊

進程ID不是唯一的,因此它們是弱熵源。我們 建議不要依賴安全相關背景下的pid。

...我不能依靠PID。

我的第二個想法是將創建進程的時間存儲到數據庫。

我怎樣才能得到當前腳本創建時間?後來我如何與tasklist進行比較來檢查特定腳本是否正在運行?

我在一個共享主機上運行,​​Windows/Linux環境。

+0

關於PID在安全相關上下文中的評論是指「熵源」和像srand(getmypid());等情況。你似乎需要一些像daemontools,perp,minit之類的進程監視機制:這些機制中的大多數都會分離一個子進程並監視文件描述符和信號,以查看這個孩子是否還活着。有了你的想法,你必須對付時間問題,權限等問題(以確定當前是否存儲在數據庫中的PID過程實際上是相同的過程)。 – akira

+0

http://kr.github.io/beanstalkd/(這是一個工作隊列)BTW使用的東西整齊:誰採取某項工作有報到,它仍然是活的,在處理任務隊列中的進程。你可以在PHP中實現類似的事情還有:如果程序本身沒有及時與給定的標識符報到,你可以考慮的任務,因爲beeing中斷/失敗等等看信號/催生/派生的子流程的filedescriptors仍然容易恕我直言。 – akira

+0

可能是有用的:https://github.com/CHH/kue - '一個簡約,通用和框架獨立接口的工作隊列' – akira

回答

1

這一切都取決於你的訪問級別定位的機器。您可以使用PHP CLI,儲存的PID(它們是唯一在特定時間點,所以你不會有2個進程具有相同的PID運行)和grep他們的ps -ax輸出,以檢查它們是否正在運行。如果不是 - 從數據庫中刪除它們,這樣就不會出現相同PID發生的問題。

+0

問題是,PID是重用一旦它下來... – Red

+0

不是即刻。您將能夠將其標記爲在數據庫中完成。包括日期/時間也不能區分。 –

1

php.net/getmypid

很少的修改,以禁用非CLI訪問。

腳本可以使用/usr/bin/php script.php執行。

另外使用nohup /usr/bin/php script.php > nohup.out &在後臺啓動nohup進程。

#!/usr/bin/php 
<?php 

if (PHP_SAPI !== 'cli') { 
    die("Cmd line access only!\n"); 
} 

define('LOCK_FILE', "/var/run/".basename($argv[0], ".php").".lock"); // can also use /tmp 
if(isLocked()) die("Already running.\n"); 

# The rest of your script goes here.... 
echo "Hello world!\n"; 
sleep(30); 

unlink(LOCK_FILE); 
exit(0); 

function isLocked() 
{ 
    # If lock file exists, check if stale. If exists and is not stale, return TRUE 
    # Else, create lock file and return FALSE. 

    if(file_exists(LOCK_FILE)) 
    { 
     # check if it's stale 
     $lockingPID = trim(file_get_contents(LOCK_FILE)); 

     # Get all active PIDs. 
     $pids = explode("\n", trim(`ps -e | awk '{print $1}'`)); 

     # If PID is still active, return true 
     if(in_array($lockingPID, $pids)) return true; 

     # Lock-file is stale, so kill it. Then move on to re-creating it. 
     echo "Removing stale lock file.\n"; 
     unlink(LOCK_FILE); 
    } 

    file_put_contents(LOCK_FILE, getmypid() . "\n"); 
    return false; 

} 
?>