2 回答

TA貢獻(xiàn)1804條經(jīng)驗(yàn) 獲得超8個(gè)贊
我認(rèn)為這就是你需要的:
cmd := exec.Command(command, arguments...)
// This sets up a process group which we kill later.
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
if err := cmd.Start(); err != nil {
return err
}
// buffered chan is important so the goroutine does't
// get blocked and stick around if the function returns
// after the timeout
done := make(chan error, 1)
go func() {
done <- cmd.Wait()
}()
select {
case err := <-done:
// this will be nil if no error
return err
case <-time.After(time.Second):
// We created a process group above which we kill here.
pgid, err := syscall.Getpgid(cmd.Process.Pid)
if err != nil {
return err
}
// note the minus sign
if err := syscall.Kill(-pgid, 15); err != nil {
return err
}
return fmt.Errorf("Timeout")
}

TA貢獻(xiàn)1773條經(jīng)驗(yàn) 獲得超3個(gè)贊
目前尚不清楚您是否可以控制這些子進(jìn)程。如果是這樣,您可以考慮使用以下 Linux 功能(您也沒有說明它是否特定于操作系統(tǒng))。
這行代碼要求內(nèi)核在父母去世時(shí)向孩子發(fā)送一個(gè) SIGHUP。這樣你的 Go 進(jìn)程就可以殺死父進(jìn)程,它會(huì)自動(dòng)殺死所有的子進(jìn)程。不僅如此,它永遠(yuǎn)不會(huì)失敗!內(nèi)核在那個(gè)上非常好。
prctl(PR_SET_PDEATHSIG, SIGHUP);
當(dāng)然,如果你這樣做,就會(huì)出現(xiàn)競(jìng)爭(zhēng)條件。也就是說,當(dāng)孩子調(diào)用這個(gè)prctl()函數(shù)時(shí),父母可能已經(jīng)死了,在這種情況下,孩子需要立即退出。
if(getppid() != parent_pid)
{
exit(1);
}
所以避免競(jìng)爭(zhēng)條件的完整代碼是:
// must happen before the fork() call
const pid_t parent_pid = getpid();
const pid_t child_pid = fork();
if(child_pid != 0)
{
// fork() failed (child_pid == -1) or worked (an actual PID)
...
return;
}
prctl(PR_SET_PDEATHSIG, SIGHUP);
if(getppid() != parent_pid)
{
exit(1);
}
注意:通常SIGHUP用于這種情況。您可能還想考慮其他信號(hào),特別是如果孩子處理管道/套接字(在這種情況下您可能會(huì)忽略SIGHUP?。┗騍IGHUP由于其他原因需要處理。
現(xiàn)在,如果您對(duì)子進(jìn)程的代碼沒有任何控制權(quán)……您可以嘗試通過搜索所有子進(jìn)程來從 Go 應(yīng)用程序中殺死每個(gè)子進(jìn)程,一個(gè)一個(gè)地殺死它們,然后殺死父進(jìn)程。但是,您總是會(huì)遇到無法避免的競(jìng)爭(zhēng)條件,除非您可以阻止整個(gè)子樹創(chuàng)建新進(jìn)程。如果你能做到這一點(diǎn),那么只需注冊(cè)所有這些孩子的PID并一個(gè)一個(gè)地殺死他們。
當(dāng)然,如果能建個(gè)群就更好了。像上面的 SIGHUP 一樣,殺死一個(gè)組的所有成員是由內(nèi)核完成的,它不會(huì)錯(cuò)過任何進(jìn)程。
- 2 回答
- 0 關(guān)注
- 416 瀏覽
添加回答
舉報(bào)