首頁  >  文章  >  後端開發  >  如何在 Go 中分離長時間運行的進程並避免殭屍?

如何在 Go 中分離長時間運行的進程並避免殭屍?

Linda Hamilton
Linda Hamilton原創
2024-11-01 07:51:31177瀏覽

How to Detach a Long-Running Process in Go and Avoid Zombies?

在Go 中執行指令並將其與進程分離

問題:

問題:
  • 問題:
  • 你需要在Go 中執行一個長時間運行的進程,並確保:
  • stdout 被重定向到一個檔案。

進程的使用者受到控制。 進程當你的程式退出時不會死亡。

如果崩潰,進程不會變成殭屍。

你取得正在運行的進程的 PID。

嘗試的解決方案:

您嘗試使用cmd.Start() 和cmd.Process.Release(),但它們並不能阻止程式退出時進程變成殭屍行程。你也希望進程盡可能獨立,有自己的父PID、群組PID等

<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>
解決方案:

你面臨的問題是Linux 不允許您在進程啟動後更改其父進程。如果你想要一個真正獨立的進程,它需要由其他東西啟動,例如 atd 或 systemd。 要解決殭屍和進程終止問題,你可以使用像 [go-reap] 這樣的函式庫(https://github.com/hashicorp/go-reap)。它提供了一個 Reaper 服務,可以自動收割孤立的子程序並報告其退出狀態。 這是一個使用go-reap 啟動分離進程的範例:透過使用go-reap並在進程退出時收割該進程,可以確保它不會變成殭屍,並且可以追蹤它的退出狀態。

以上是如何在 Go 中分離長時間運行的進程並避免殭屍?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn