首頁  >  文章  >  後端開發  >  如何在 Go 中運行長時間運行的進程並將其與父進程分開?

如何在 Go 中運行長時間運行的進程並將其與父進程分開?

Linda Hamilton
Linda Hamilton原創
2024-10-29 18:31:43232瀏覽

How to Run a Long-Running Process in Go and Detach It from the Parent Process?

在Go 中運行命令並將其從進程中分離

問題

我需要在Go 中執行一個長時間運行的進程,符合以下要求:

  1. 將進程的標準輸出重新導向至檔案。
  2. 控制進程的使用者。
  3. 確保進程在我的程式退出後繼續運作。
  4. 防止行程崩潰時變成殭屍。
  5. 取得正在運行的進程的 PID。

我正在以root 權限運行我的程序,並擁有嘗試使用exec.Command() 和syscall.SysProcAttr 解決方案,但當我向程式發送SIGTERM/SIGKILL 時失敗,導致底層進程崩潰。我想將進程作為守護程式運行,與程式的控制分開。

解決方案

強烈建議使用外部庫,例如 github.com/hashicorp/go-reap它有效地解決了這個問題。但是,如果您喜歡自訂實現,可以考慮以下方法:

  1. 重定向標準輸出:使用cmd.Stdout = stdLogFile 將進程的stdout 重定向到指定文件.
  2. 控制使用者: 設定cmd.SysProcAttr = &syscall.SysProcAttr{Credential: &syscall.Credential{Uid: uid}} 來控制進程的使用者。
  3. 從進程中分離:使用 go func() { cmd.Wait() }() 在單獨的 goroutine 中執行指令,以防止其成為殭屍。
  4. 取得 PID:使用 cmd.Process.Pid 取得正在執行的進程的 PID。

注意

重要的是要承認,不可能完全分離進程就進程繼承而言,父進程和子進程。所有進程都必須有一個父進程,如果父進程死亡,子進程將成為孤兒並被PID 1(init)收養。換句話說,子進程不能有與啟動它的初始進程不同的父進程。

為了確保進程在父進程退出後繼續運行,請考慮使用專用的進程管理器,如 systemd 或 docker,它可以管理孤立進程並確保它們繼續執行。其他潛在的解決方案包括編寫自訂守護程式或使用 go-daemon 等函式庫來獨立於父程式管理程式的生命週期。

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

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