第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

你如何在 Go 代碼超時(shí)時(shí)殺死一個(gè)進(jìn)程及其子進(jìn)程?

你如何在 Go 代碼超時(shí)時(shí)殺死一個(gè)進(jìn)程及其子進(jìn)程?

Go
守候你守候我 2021-11-08 19:29:34
我有一種情況,我需要在一段時(shí)間后終止一個(gè)進(jìn)程。我開始這個(gè)過程,然后:case <-time.After(timeout):        if err := cmd.Process.Kill(); err != nil {            return 0, fmt.Errorf("Failed to kill process: %v", err)        }殺死進(jìn)程。但它只會(huì)殺死父進(jìn)程,而不是主進(jìn)程啟動(dòng)的 5-10 個(gè)子進(jìn)程。我還嘗試創(chuàng)建一個(gè)進(jìn)程組,然后執(zhí)行以下操作:syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)殺死主進(jìn)程和孫進(jìn)程,但不起作用。有沒有其他方法可以終止進(jìn)程。
查看完整描述

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")

}


查看完整回答
反對(duì) 回復(fù) 2021-11-08
?
慕容3067478

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)程。


查看完整回答
反對(duì) 回復(fù) 2021-11-08
  • 2 回答
  • 0 關(guān)注
  • 416 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)