從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;
}
?>
關於PID在安全相關上下文中的評論是指「熵源」和像srand(getmypid());等情況。你似乎需要一些像daemontools,perp,minit之類的進程監視機制:這些機制中的大多數都會分離一個子進程並監視文件描述符和信號,以查看這個孩子是否還活着。有了你的想法,你必須對付時間問題,權限等問題(以確定當前是否存儲在數據庫中的PID過程實際上是相同的過程)。 – akira
http://kr.github.io/beanstalkd/(這是一個工作隊列)BTW使用的東西整齊:誰採取某項工作有報到,它仍然是活的,在處理任務隊列中的進程。你可以在PHP中實現類似的事情還有:如果程序本身沒有及時與給定的標識符報到,你可以考慮的任務,因爲beeing中斷/失敗等等看信號/催生/派生的子流程的filedescriptors仍然容易恕我直言。 – akira
可能是有用的:https://github.com/CHH/kue - '一個簡約,通用和框架獨立接口的工作隊列' – akira