在Go 中終止子程序:解決超時問題
在提供的Go 程式碼片段中,儘管設定了2 秒的超時並嘗試使用訊號終止子進程,該進程將持續存在並且「完成等待」仍然不列印。此行為表示該進程在超出指定時間後仍保持活動狀態。
此問題的根源在於使用 cmd.Process.Signal() 來終止子程序。需要注意的是,該函數僅向主進程發送訊號,而不向其子進程發送訊號。為了有效終止子進程,需要定位包含子進程的進程組,這可以使用以下方法來完成:
// First, create the command and set up its attributes cmd := exec.Command( some_command ) cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} // Then, start the command cmd.Start() // Next, obtain the process group ID of the child process pgid, err := syscall.Getpgid(cmd.Process.Pid) if err == nil { // If the process group ID is successfully obtained, terminate it syscall.Kill(-pgid, 15) // note the minus sign } // Finally, wait for the command to complete cmd.Wait()
透過在syscall.SysProcAttr 中將Setpgid 設為true,我們指示作業系統為子進程建立一個新的進程組,確保傳送到父進程的訊號不會影響子進程。 -pgid 中的減號確保訊號傳送到進程組的所有成員,包括任何子程序。
此解決方案是特定於平台的,可能不適用於所有作業系統。然而,據報導它可以在 OSX Yosemite 和各種 Linux 發行版上運行,而其在 Windows 和 BSD 上的兼容性仍不確定。
以上是Go 發生逾時時如何可靠地終止子進程?的詳細內容。更多資訊請關注PHP中文網其他相關文章!