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 に設定することで、次のように指示します。 OS は子プロセスの新しいプロセス グループを作成し、親プロセスに送信されたシグナルが子プロセスに影響を与えないようにします。 -pgid のマイナス記号により、子プロセスを含むプロセス グループのすべてのメンバーにシグナルが送信されます。
このソリューションはプラットフォーム固有であり、すべてのオペレーティング システムで動作するとは限りません。ただし、OSX Yosemite やさまざまな Linux ディストリビューションで動作すると報告されていますが、Windows と BSD での互換性はまだ不確かです。
以上がタイムアウトが発生したときに Go で子プロセスを確実に強制終了するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。