欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang 設置進程退出時kill所有子進程的三種方法

 更新時間:2025年09月07日 10:07:45   作者:phiilo  
本文主要介紹了golang 設置進程退出時kill所有子進程的三種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

在 Go 語言中使用 os/exec.Command 啟動子進程時,默認情況下子進程不會隨父進程(當前進程)的退出而自動終止,因為子進程會被系統(tǒng)(如 init 或系統(tǒng)進程管理器)收養(yǎng)并繼續(xù)運行。要實現(xiàn)“父進程退出時自動終止子進程”的功能,需要根據(jù)操作系統(tǒng)采用不同的策略。沒有完美的跨平臺標準解決方案,但以下是常見實現(xiàn)方式,包括手動處理信號和平臺特定機制。以下解釋逐步如何實現(xiàn),并提供代碼示例。

1.通用方式:捕獲信號并手動終止子進程(跨平臺,適用于正常退出和可捕獲信號)

這是一種簡單、跨平臺的做法:父進程監(jiān)聽退出信號(如 SIGINT、SIGTERM),在收到信號時主動殺死子進程。這種方式適用于父進程正常退出或被可捕獲信號終止的情況,但如果父進程被 kill -9 (SIGKILL) 強制殺死,則無效(因為 SIGKILL 無法捕獲)。

步驟

  • 使用 signal.Notify 監(jiān)聽信號。
  • 啟動子進程后,記錄 PID。
  • 在信號處理中逐個終止子進程(如果需要殺死子進程的子進程,可使用進程組,詳見下文)。

代碼示例

package main

import (
    "context"
    "fmt"
    "os"
    "os/exec"
    "os/signal"
    "syscall"
    "time"
)

func main() {
    // 啟動子進程,例如運行 "sleep 60"
    cmd := exec.Command("sleep", "60")
    if err := cmd.Start(); err != nil {
        fmt.Println("Start error:", err)
        return
    }
    fmt.Printf("Child process started with PID: %d\n", cmd.Process.Pid)

    // 監(jiān)聽信號
    sigs := make(chan os.Signal, 1)
    signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

    //  goroutine 處理信號
    go func() {
        sig := <-sigs
        fmt.Printf("Received signal: %v\n", sig)
        if cmd.Process != nil {
            if err := cmd.Process.Kill(); err != nil {
                fmt.Println("Kill error:", err)
            }
        }
        os.Exit(0)
    }()

    // 等待子進程正常結束(可選,如果子進程有自己的退出邏輯)
    if err := cmd.Wait(); err != nil {
        fmt.Println("Wait error:", err)
    }
}

擴展:使用進程組殺死子進程及其后代(Unix-like 系統(tǒng))
要殺死整個進程樹:

cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
// 在殺死時:
syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)

2.Linux 特定:使用 Pdeathsig 自動發(fā)送信號

在 Linux 上,可以使用 syscall.SysProcAttr.Pdeathsig 設置當父進程(或創(chuàng)建線程)死亡時,內(nèi)核自動向子進程發(fā)送指定信號(如 SIGTERM 或 SIGKILL)。這實現(xiàn)了“自動”終止,即使父進程被 SIGKILL 殺死。

注意

  • 只適用于 Linux(基于 prctl(PR_SET_PDEATHSIG))。
  • 如果子進程是多線程的,可能有邊緣問題(見 Go issue #27505)。
  • 子進程需要能響應信號(例如,如果它忽略 SIGTERM,則用 SIGKILL)。

代碼示例

package main

import (
    "fmt"
    "os/exec"
    "syscall"
)

func main() {
    cmd := exec.Command("sleep", "60")
    cmd.SysProcAttr = &syscall.SysProcAttr{
        Pdeathsig: syscall.SIGKILL,  // 或 syscall.SIGTERM
    }
    if err := cmd.Start(); err != nil {
        fmt.Println("Start error:", err)
        return
    }
    fmt.Printf("Child process started with PID: %d\n", cmd.Process.Pid)

    // 父進程可以繼續(xù)其他工作,或直接退出測試
    // cmd.Wait()  // 可選
}

3.Windows 特定:使用 Job Object 自動終止

在 Windows 上,沒有直接等價于 Pdeathsig 的機制,但可以使用 Windows Job Object 將進程分組,并設置 JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 標志:當 Job Object 的最后一個句柄關閉(父進程退出)時,自動殺死所有關聯(lián)進程。

注意

  • Go 標準庫不直接支持,需要使用 golang.org/x/sys/windows 包調(diào)用 Windows API。
  • 需要安裝依賴:go get golang.org/x/sys/windows。
  • 這會終止子進程及其后代。

代碼示例(簡化版,需要處理錯誤和清理):

package main

import (
    "fmt"
    "os/exec"
    "syscall"
    "unsafe"

    "golang.org/x/sys/windows"
)

func main() {
    // 創(chuàng)建 Job Object
    job, err := windows.CreateJobObject(nil, nil)
    if err != nil {
        fmt.Println("CreateJobObject error:", err)
        return
    }
    defer windows.CloseHandle(job)

    // 設置 Kill on Job Close
    var info windows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION
    info.BasicLimitInformation.LimitFlags = windows.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
    err = windows.SetInformationJobObject(
        job,
        windows.JobObjectExtendedLimitInformation,
        uintptr(unsafe.Pointer(&info)),
        uint32(unsafe.Sizeof(info)),
    )
    if err != nil {
        fmt.Println("SetInformationJobObject error:", err)
        return
    }

    // 將當前進程分配到 Job Object(子進程會繼承)
    err = windows.AssignProcessToJobObject(job, windows.CurrentProcess())
    if err != nil {
        fmt.Println("AssignProcessToJobObject error:", err)
        return
    }

    // 啟動子進程
    cmd := exec.Command("timeout", "/t", "60")  // Windows 等價于 sleep
    if err := cmd.Start(); err != nil {
        fmt.Println("Start error:", err)
        return
    }
    fmt.Printf("Child process started with PID: %d\n", cmd.Process.Pid)

    // cmd.Wait()  // 可選
}

說明:子進程啟動后會自動關聯(lián) Job Object(因為父進程已關聯(lián))。父進程退出時,Job Object 關閉,子進程被終止。

其他注意

  • 跨平臺實現(xiàn):可以使用條件編譯(//go:build linux 等)來區(qū)分平臺特定代碼。對于通用場景,優(yōu)先使用信號捕獲方式。
  • 測試:在 Unix 上用 kill <pid> 測試;在 Windows 上用 Task Manager 殺死父進程。
  • 局限性:沒有方式能 100% 保證在所有情況下(如父進程崩潰)自動終止,尤其是跨平臺。如果子進程是 daemon 或忽略信號,可能需要額外處理。

到此這篇關于golang 設置進程退出時kill所有子進程的三種方法的文章就介紹到這了,更多相關Golang殺死子進程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家! 

相關文章

  • Go語言中同一個package中函數(shù)互相調(diào)用為undefined的解決

    Go語言中同一個package中函數(shù)互相調(diào)用為undefined的解決

    這篇文章主要介紹了Go語言中同一個package中函數(shù)互相調(diào)用為undefined的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • 一文掌握Go語言并發(fā)編程必備的Mutex互斥鎖

    一文掌握Go語言并發(fā)編程必備的Mutex互斥鎖

    Go 語言提供了 sync 包,其中包括 Mutex 互斥鎖、RWMutex 讀寫鎖等同步機制,本篇博客將著重介紹 Mutex 互斥鎖的基本原理,需要的可以參考一下
    2023-04-04
  • Go語言利用heap實現(xiàn)優(yōu)先級隊列

    Go語言利用heap實現(xiàn)優(yōu)先級隊列

    這篇文章主要為大家詳細介紹了Go語言中heap的使用以及如何利用heap實現(xiàn)優(yōu)先級隊列的相關資料,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-05-05
  • Go語言標準輸入輸出庫的基本使用教程

    Go語言標準輸入輸出庫的基本使用教程

    輸入輸出在任何一門語言中都必須提供的一個功能,下面這篇文章主要給大家介紹了關于Go語言標準輸入輸出庫的基本使用,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-02-02
  • Linux環(huán)境下編譯并運行go項目的全過程

    Linux環(huán)境下編譯并運行go項目的全過程

    Go語言是Google的開源編程語言,廣泛應用于云計算、分布式系統(tǒng)開發(fā)等領域,在Linux上也有大量的應用場景,這篇文章主要給大家介紹了關于Linux環(huán)境下編譯并運行go項目的相關資料,需要的朋友可以參考下
    2023-11-11
  • golang中拿slice當queue和拿list當queue使用分析

    golang中拿slice當queue和拿list當queue使用分析

    這篇文章主要為大家介紹了golang?中拿slice當queue和拿list當queue使用分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • 詳解Go語言微服務開發(fā)框架之Go chassis

    詳解Go語言微服務開發(fā)框架之Go chassis

    分布式系統(tǒng)中每個進程的動態(tài)配置管理及運行時熱加載就成為了一個亟待解決的問題。go chassis汲取了netflix的archaius框架經(jīng)驗,并做出來自己的創(chuàng)新特性。
    2021-05-05
  • 搭建Go語言的ORM框架Gorm的具體步驟(從Java到go)

    搭建Go語言的ORM框架Gorm的具體步驟(從Java到go)

    很多朋友不知道如何使用Goland軟件,搭建一個ORM框架GORM,今天小編給大家分享一篇教程關于搭建Go語言的ORM框架Gorm的具體步驟(從Java到go),感興趣的朋友跟隨小編一起學習下吧
    2022-09-09
  • Golang中使用Date進行日期格式化(沿用Java風格)

    Golang中使用Date進行日期格式化(沿用Java風格)

    這篇文章主要介紹了Golang中使用Date進行日期格式化,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-04-04
  • Golang測試框架goconvey進行單元測試流程介紹

    Golang測試框架goconvey進行單元測試流程介紹

    goconvey是一款針對Golang的測試框架,可以管理和運行測試用例,同時提供了豐富的斷言函數(shù),并支持很多Web界面特性,這篇文章主要介紹了使用goconvey進行單元測試流程,感興趣的同學可以參考下文
    2023-05-05

最新評論