Go でコマンドを実行し、プロセスから切り離す
問題:
Go で長時間実行プロセスを実行し、次のことを確認します。
試行された解決策:
cmd.Start() と cmd.Process.Release() を使用しようとしましたが、プログラムの終了時にプロセスがゾンビになるのを防ぐことはできません。また、独自の親 PID、グループ PID などを使用して、プロセスをできるだけ分離する必要もあります。
解決策:
直面している問題は次のとおりです。 Linux では、プロセスが開始された後にプロセスの親を変更することはできません。本当に分離されたプロセスが必要な場合は、atd や systemd などの別のものによって開始する必要があります。
ゾンビやプロセス終了の問題に対処するには、[go-reap] のようなライブラリを使用できます。 (https://github.com/bashicorp/go-reap)。これは、孤立した子プロセスを自動的に取得し、その終了ステータスを報告する Reaper サービスを提供します。
ここでは、go-reap を使用して切り離されたプロセスを開始する例を示します。
<code class="go">package main import ( "context" "fmt" "os/exec" "github.com/hashicorp/go-reap" ) func main() { // Start a Reaper service to reap orphaned processes. doneCh := make(chan struct{}) ctx, cancel := context.WithCancel(context.Background()) reaper := reap.NewReaper(cancel) go reaper.Run(ctx) defer reaper.Stop() // Execute a command in a detached process. cmd := exec.Command("my-long-running-command", "args") pid, err := reaper.Reap(cmd) if err != nil { fmt.Printf("Error reaping process: %v\n", err) return } fmt.Printf("PID of detached process: %v\n", pid) // Wait for the detached process to complete. exitStatus, err := reaper.WaitPid(pid) if err != nil { fmt.Printf("Error waiting for process: %v\n", err) return } fmt.Printf("Detached process exited with status: %v\n", exitStatus) // Stop the Reaper service when done. close(doneCh) }</code>
Go-reap を使用する場合プロセスが終了するときにそのプロセスを刈り取ることで、プロセスがゾンビにならないことを確認し、終了ステータスを追跡できます。
以上がGo で長時間実行されているプロセスを切り離してゾンビを回避するには?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。