2011-01-19 55 views
6

我正在用popen()打開一個長時間運行的進程。爲了調試,我想在完成之前終止該過程。調用pclose()只是阻塞,直到孩子完成。用popen()打開殺死進程?

我該如何殺死這個過程?我沒有看到任何簡單的方法來從popen()返回的資源中獲取pid,以便我可以向它發送一個信號。

我想我可以做一些kludgey並試圖捏造PID爲使用某種命令行兩輪牛車的輸出...

+0

這不是一個真正的答案,因爲它適用於C而不是PHP,但請參閱此鏈接以獲取建議:http://www.monkey.org/openbsd/archive/misc/0112/msg00360.html – 2011-01-19 04:14:50

回答

7

那麼,降落在一個解決方案:我切換回proc_open()而不是popen()。然後,它的那樣簡單:

$s = proc_get_status($p); 
posix_kill($s['pid'], SIGKILL); 
proc_close($p); 
+0

我和`proc_open()`有同樣的問題,所以我嘗試了更簡單的`popen()`,希望這會有所幫助。當時我沒有意識到* * pclose()和`proc_close()`阻塞,直到孩子終止。一旦你意識到這一點,那麼你必須殺死孩子。要殺死孩子,你需要使用pid,這並不是用`popen()`完全可用的。 `proc_open()`做一切`popen()`做的,然後一些。 – 2011-01-19 04:20:44

0

使用kill功能只需發送kill(或中止)信號:

+0

棘手的部分在搞清楚哪個pid要殺死的時候做得很好:)一旦你確定你有正確的pid,那麼你可以調用php的`posix_kill()`。我想現在回想起來,我可以從ps中獲得孩子pid的列表,因爲很容易找出我自己的pid。 – 2011-01-19 04:16:36

0

您可以找到PID,那你真的其父做檢查:

// Find child processes according to current pid 
$res = trim(exec('ps -eo pid,ppid |grep "'.getmypid().'" |head -n2 |tail -n1')); 
if (preg_match('~^(\d+)\s+(\d+)$~', $res, $pid) !== 0 && (int) $pid[2] === getmypid()) 
{ 
    // I'm the parent PID, just send a KILL 
    posix_kill((int) $pid[1], 9); 
} 

它的工作非常好快的CGI PHP的服務器上。