最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

golang 設(shè)置進(jìn)程退出時kill所有子進(jìn)程的三種方法

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

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

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

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

步驟

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

代碼示例

package main

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

func main() {
    // 啟動子進(jìn)程,例如運行 "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)
    }()

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

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

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

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

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

注意

  • 只適用于 Linux(基于 prctl(PR_SET_PDEATHSIG))。
  • 如果子進(jìn)程是多線程的,可能有邊緣問題(見 Go issue #27505)。
  • 子進(jìn)程需要能響應(yīng)信號(例如,如果它忽略 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)

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

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

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

注意

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

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

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)

    // 設(shè)置 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
    }

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

    // 啟動子進(jìn)程
    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()  // 可選
}

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

其他注意

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

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

相關(guān)文章

  • 使用Gin框架搭建一個Go Web應(yīng)用程序的方法詳解

    使用Gin框架搭建一個Go Web應(yīng)用程序的方法詳解

    在本文中,我們將要實現(xiàn)一個簡單的 Web 應(yīng)用程序,通過 Gin 框架來搭建,主要支持用戶注冊和登錄,用戶可以通過注冊賬戶的方式創(chuàng)建自己的賬號,并通過登錄功能進(jìn)行身份驗證,感興趣的同學(xué)跟著小編一起來看看吧
    2023-08-08
  • Go語言單元測試的實現(xiàn)及用例

    Go語言單元測試的實現(xiàn)及用例

    在日常開發(fā)中,我們通常需要針對現(xiàn)有的功能進(jìn)行單元測試,以驗證開發(fā)的正確性,本文主要介紹了Go語言單元測試的實現(xiàn)及用例,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • golang的協(xié)程上下文的具體使用

    golang的協(xié)程上下文的具體使用

    golang的context?主要用來在?goroutine?之間傳遞上下文信息,包括:取消信號、超時時間、截止時間、k-v?等,本文就詳細(xì)的來介紹一下golang的協(xié)程上下文的具體使用,感興趣的可以了解一下
    2022-04-04
  • linux下通過go語言獲得系統(tǒng)進(jìn)程cpu使用情況的方法

    linux下通過go語言獲得系統(tǒng)進(jìn)程cpu使用情況的方法

    這篇文章主要介紹了linux下通過go語言獲得系統(tǒng)進(jìn)程cpu使用情況的方法,實例分析了Go語言使用linux的系統(tǒng)命令ps來分析cpu使用情況的技巧,需要的朋友可以參考下
    2015-03-03
  • 解決go獲取文件md5值不正確的問題

    解決go獲取文件md5值不正確的問題

    本文主要介紹了解決go獲取文件md5值不正確的問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-01-01
  • Go語言中json序列化優(yōu)化技巧

    Go語言中json序列化優(yōu)化技巧

    在Go語言開發(fā)中,JSON因其簡潔和廣泛的兼容性,通常被用作數(shù)據(jù)交換的主要序列化格式,本文將探討JSON希望對大家有所幫助序列化的一些局限性,也算是一個小坑吧,并給出一些常用的解決方案,
    2024-11-11
  • Golang Mutex互斥鎖深入理解

    Golang Mutex互斥鎖深入理解

    這篇文章主要為大家介紹了Golang Mutex互斥鎖深入理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Golang性能優(yōu)化的技巧分享

    Golang性能優(yōu)化的技巧分享

    性能優(yōu)化的前提是滿足正確可靠、簡潔清晰等質(zhì)量因素,針對?Go語言特性,本文為大家整理了一些Go語言相關(guān)的性能優(yōu)化建議,感興趣的可以了解一下
    2023-07-07
  • go語言實現(xiàn)一個簡單的http客戶端抓取遠(yuǎn)程url的方法

    go語言實現(xiàn)一個簡單的http客戶端抓取遠(yuǎn)程url的方法

    這篇文章主要介紹了go語言實現(xiàn)一個簡單的http客戶端抓取遠(yuǎn)程url的方法,實例分析了Go語言http操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-03-03
  • Golang如何自定義logrus日志保存為日志文件

    Golang如何自定義logrus日志保存為日志文件

    這篇文章主要給大家介紹了關(guān)于Golang如何自定義logrus日志保存為日志文件的相關(guān)資料,logrus是目前Github上star數(shù)量最多的日志庫,logrus功能強大,性能高效,而且具有高度靈活性,提供了自定義插件的功能,很多開源項目都是用了logrus來記錄其日志,需要的朋友可以參考下
    2024-02-02

最新評論

奉化市| 溧阳市| 桓仁| 苗栗市| 婺源县| 阳信县| 花垣县| 襄樊市| 鹤峰县| 石屏县| 昭苏县| 涪陵区| 英山县| 韶关市| 怀远县| 达拉特旗| 罗山县| 黑河市| 吴堡县| 义马市| 河北区| 平乐县| 长子县| 平江县| 武邑县| 马尔康县| 绍兴县| 庆阳市| 通榆县| 临沧市| 盐城市| 龙州县| 辽宁省| 台前县| 保山市| 天祝| 建宁县| 陆丰市| 林口县| 禹州市| 双峰县|