Heim  >  Artikel  >  Backend-Entwicklung  >  Wie kann man einen langwierigen Prozess in Go and Dodge Zombies trennen?

Wie kann man einen langwierigen Prozess in Go and Dodge Zombies trennen?

Linda Hamilton
Linda HamiltonOriginal
2024-11-01 07:51:31177Durchsuche

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

Befehl in Go ausführen und vom Prozess trennen

Problem:

Sie müssen Führen Sie einen lang laufenden Prozess in Go aus und stellen Sie sicher, dass:

  • Standardausgabe in eine Datei umgeleitet wird.
  • Der Benutzer des Prozesses wird kontrolliert.
  • Der Prozess stirbt nicht, wenn Ihr Programm beendet wird.
  • Der Prozess wird nicht zum Zombie, wenn er abstürzt.
  • Sie erhalten die PID des laufenden Prozesses.

Lösungsversuch:

Sie haben versucht, cmd.Start() und cmd.Process.Release() zu verwenden, aber sie verhindern nicht, dass der Prozess zu einem Zombie wird, wenn Ihr Programm beendet wird. Sie möchten außerdem, dass der Prozess so getrennt wie möglich ist, mit einer eigenen übergeordneten PID, Gruppen-PID usw.

Lösung:

Das Problem, mit dem Sie konfrontiert sind, ist dass Linux es Ihnen nicht erlaubt, das übergeordnete Element eines Prozesses zu ändern, sobald dieser gestartet ist. Wenn Sie einen wirklich getrennten Prozess wünschen, muss er von etwas anderem gestartet werden, beispielsweise von atd oder systemd.

Um die Probleme mit Zombies und der Prozessbeendigung zu beheben, können Sie eine Bibliothek wie [go-reap] verwenden. (https://github.com/hashicorp/go-reap). Es stellt einen Reaper-Dienst bereit, der verwaiste untergeordnete Prozesse automatisch erntet und ihren Exit-Status meldet.

Hier ist ein Beispiel für die Verwendung von go-reap zum Starten eines getrennten Prozesses:

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

Durch die Verwendung von go-reap und indem Sie den Prozess ernten, wenn er beendet wird, können Sie sicherstellen, dass er nicht zu einem Zombie wird und dass Sie seinen Beendigungsstatus verfolgen können.

Das obige ist der detaillierte Inhalt vonWie kann man einen langwierigen Prozess in Go and Dodge Zombies trennen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn