2010-04-29 69 views
2

我在作業工作者的作品中有一個PHP腳本;它的主要任務是檢查一個數據庫表以尋找新的工作,如果有的話,對他們採取行動。但喬布斯將現身在陣陣,之間長期的差距,所以我設計了一個睡眠週期,如:PHP <5.3.0守護進程腳本何時接收信號?

while(true) { 
    if ($jobs = get_new_jobs()) { 
    // Act upon the jobs 
    } else { 
    // No new jobs now 
    sleep(30); 
    } 
} 

好,但在某些情況下,這意味着之前新工作可能有一個30秒的延遲採取行動。由於這是一個後臺程序腳本,我想我會嘗試pcntl_signal鉤釣SIGUSR1信號促使這個腳本醒來,如:

$_isAwake = true; 
function user_sig($signo) { 
    global $_isAwake; 
    daemon_log("Caught SIGUSR1"); 
    $_isAwake = true; 
} 
pcntl_signal(SIGUSR1, 'user_sig'); 

while(true) { 
    if ($jobs = get_new_jobs()) { 
    // Act upon the jobs 
    } else { 
    // No new jobs now 
    daemon_log("No new jobs, sleeping..."); 
    $_isAwake = false; 
    $ts = time(); 
    while(time() < $ts+30) { 
     sleep(1); 
     if ($_isAwake) break; // Did a signal happen while we were sleeping? If so, stop sleeping 
    } 
    $_isAwake = true; 
    } 
} 

我打破了sleep(30)成更小的睡位,萬一一個信號不會中斷sleep()命令,認爲這會導致最多1秒的延遲,但在日誌文件中,我看到SIGUSR1在完整的30秒後才被捕獲(也許外部while循環重置)。

我發現了pcntl_signal_dispatch命令,但這隻適用於PHP 5.3及更高版本。如果我使用的是該版本,我可以在撥打if ($_isAwake)電話之前撥打該命令,但由於目前狀態,我在5.2.13上。

在PHP版本中解釋的信號隊列在什麼情況下不需要顯式調用隊列解析?我可以在睡眠循環中放入一些其他無用的命令,在那裏觸發信號隊列解析嗎?

回答

2

修復了我自己的問題:答案是「ticks」聲明。作爲Daemon進程啓動的一部分,我已經完成declare(ticks=1);操作,但是它似乎不能繼續運行到主腳本(因爲它在函數內部,包含文件中)。在while(true)之前添加一行declare(ticks=1)循環導致信號立即通過(即sleep(1)命令導致打勾,所以在從睡眠中醒來後,信號被處理)