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

Golang優(yōu)雅保持main函數(shù)不退出的辦法

 更新時間:2022年07月20日 16:08:30   作者:MiKogy_  
很多時候我們需要讓main函數(shù)不退出,讓它在后臺一直執(zhí)行,下面這篇文章主要給大家介紹了關(guān)于Golang優(yōu)雅保持main函數(shù)不退出的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下

高能預(yù)警

本文包含演示部分,請讀者自行copy代碼編譯體驗。

參考資料:sync.WaitGroup / signal.Notify / context.CancelFunc

正文

我們有時會希望我們的程序保持執(zhí)行,但是有一種情況是:我們的代碼全部塞入go routine時,主函數(shù)會立刻退出,本文將和大家分享如何讓main函數(shù)優(yōu)雅地保持執(zhí)行。

問題演示:

func main() {
    go func() {
        for i := 0; i<10000;i ++ {
            fmt.Println(i)
        }
    }()
}

此時我們可以看到,控制臺幾乎不會輸出任何內(nèi)容。究其原因,是主函數(shù)在go routine執(zhí)行前就已經(jīng)結(jié)束,也就是說go routine不會阻塞主函數(shù)。

可能有些讀者會想到,我直接加個死循環(huán)在下面,讓主函數(shù)不退出不就行啦?博主表示十分贊同,因為博主就是采用這個方法,導(dǎo)致服務(wù)器跑滿CPU從而不停的告警。

那么解決辦法是:讓死循環(huán)慢一點執(zhí)行,即添加以下內(nèi)容:

    for {
        time.Sleep(time.Second)
    }

但是在博主的完美主義光環(huán)加持下,還是希望我們的代碼能更加優(yōu)雅,下面將介紹另外三種比較優(yōu)雅的保持main函數(shù)的辦法。

解決辦法演示

操作系統(tǒng)信號阻塞

先上代碼:

func main() {
    c := make(chan os.Signal)
    signal.Notify(c)
    go func() {
        fmt.Println("Go routine running")
        time.Sleep(3*time.Second)
        fmt.Println("Go routine done")
    }()
    <-c
    fmt.Println("bye")
}

官網(wǎng)機(jī)翻:signal.Notify()方法使信號將傳入c。如果沒有提供信號,所有傳入的信號將被中繼到c。

  • 這里我們創(chuàng)建了一個os.Signal類型的管道。當(dāng)管道為空的時候,讀管道操作“<-”會阻塞住,直到我們向進(jìn)程發(fā)送一個信號(例如 Ctrl+C),才會繼續(xù)執(zhí)行該操作后面的代碼。

上下文操作阻塞

再上代碼:

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()
    go func() {
        fmt.Println("Go routine running")
        time.Sleep(3 * time.Second)
        fmt.Println("Go routine done")
        cancel()
    }()
    <-ctx.Done()
    fmt.Println("bye")
}

官網(wǎng)機(jī)翻:CancelFunc() 通知操作放棄其(當(dāng)前的)工作。CancelFunc() 不會等待工作停止。

  • 這也是一個十分優(yōu)雅的辦法,我們創(chuàng)建一個可以終止的上下文——context.WithCancel(),并在go routine執(zhí)行完畢時調(diào)用其返回的CancelFunc() 方法,即表示該上下文已經(jīng)結(jié)束了。而在這之前,我們會使用<-ctx.Done()來一直等待上下文的結(jié)束,也就是說main函數(shù)被成功阻塞,并等待go routine執(zhí)行完畢并執(zhí)行了cancel()方法后優(yōu)雅退出。

WaitGroup阻塞

然后上代碼:

func main() {
    wg := &sync.WaitGroup{}
    wg.Add(2)
    go func() {
        time.Sleep(3*time.Second)
        fmt.Println("3 second passed")
        wg.Done()
    }()
    go func() {
        time.Sleep(5*time.Second)
        fmt.Println("5 second passed")
        wg.Done()
    }()
    wg.Wait()
    fmt.Println("bye")
}

官網(wǎng)機(jī)翻:WaitGroup 等待一組 go routine 完成。主 go routine 調(diào)用 Add() 來設(shè)置要等待的 go routine 的數(shù)量。

  • 我們首先創(chuàng)建一個WaitGroup{}對象,然后調(diào)用Add()方法,在里面?zhèn)魅胛覀兘酉聛頃?chuàng)建的go routine的數(shù)量,每當(dāng)我們執(zhí)行完一個go routine時,調(diào)用一次Done()方法,使得正執(zhí)行的go routine的數(shù)量減一,當(dāng)減到0時,Wait()方法將不再等待(阻塞),使main函數(shù)繼續(xù)向下執(zhí)行。

小結(jié)

以上就是我們告別for {}或者select {},并優(yōu)雅地阻塞主函數(shù)的三種辦法,也是博主作為新手時對Go語言特性的入門級體驗。

總結(jié)

到此這篇關(guān)于Golang優(yōu)雅保持main函數(shù)不退出的文章就介紹到這了,更多相關(guān)Golang main函數(shù)不退出內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • golang中為什么Response.Body需要被關(guān)閉詳解

    golang中為什么Response.Body需要被關(guān)閉詳解

    這篇文章主要給大家介紹了關(guān)于golang中為什么Response.Body需要被關(guān)閉的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • golang 40行代碼實現(xiàn)通用協(xié)程池

    golang 40行代碼實現(xiàn)通用協(xié)程池

    golang協(xié)程機(jī)制很方便的解決了并發(fā)編程的問題,但是協(xié)程并不是沒有開銷的,所以也需要適當(dāng)限制一下數(shù)量。這篇文章主要介紹了golang 40行代碼實現(xiàn)通用協(xié)程池,需要的朋友可以參考下
    2018-08-08
  • 使用go語言將單反斜杠改為雙反斜杠的方法

    使用go語言將單反斜杠改為雙反斜杠的方法

    最近開發(fā)的時候遇到這么個問題,就是在window上獲取了文件目錄的字段,然后將這個絕對路徑保存到數(shù)據(jù)庫,但是前端展示的時候路徑的雙反斜杠變成了單反斜杠,本文給大家介紹了使用go語言將單反斜杠改為雙反斜杠的方法,需要的朋友可以參考下
    2024-01-01
  • go語言實現(xiàn)將重要數(shù)據(jù)寫入圖片中

    go語言實現(xiàn)將重要數(shù)據(jù)寫入圖片中

    本文給大家分享的是go語言實現(xiàn)將數(shù)據(jù)的二進(jìn)制形式寫入圖像紅色通道數(shù)據(jù)二進(jìn)制的低位,從而實現(xiàn)將重要數(shù)據(jù)隱藏,有需要的小伙伴參考下吧。
    2015-03-03
  • GO語言實現(xiàn)簡單的目錄復(fù)制功能

    GO語言實現(xiàn)簡單的目錄復(fù)制功能

    這篇文章主要介紹了GO語言實現(xiàn)簡單的目錄復(fù)制功能,通過新建及復(fù)制內(nèi)容等操作最終實現(xiàn)復(fù)制目錄的功能效果,具有一定的參考借鑒價值,需要的朋友可以參考下
    2014-12-12
  • go語言實現(xiàn)十大常見的排序算法示例

    go語言實現(xiàn)十大常見的排序算法示例

    這篇文章主要為大家介紹了go語言實現(xiàn)十大常見的排序算法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • Go語言實現(xiàn)簡單Web服務(wù)器的方法

    Go語言實現(xiàn)簡單Web服務(wù)器的方法

    這篇文章主要介紹了Go語言實現(xiàn)簡單Web服務(wù)器的方法,實例分析了Web服務(wù)器的實現(xiàn)原理與相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • 一文搞懂Go語言中條件語句的使用

    一文搞懂Go語言中條件語句的使用

    這篇文章主要介紹了Go語言中五個常用條件語句的使用,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • GO語言字符串常用操作小結(jié)

    GO語言字符串常用操作小結(jié)

    本文主要介紹了GO語言字符串常用操作小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Go數(shù)組與切片輕松掌握

    Go數(shù)組與切片輕松掌握

    在Java的核心庫中,集合框架可謂鼎鼎大名:Array、List、Set等等,隨便拎一個出來都值得開發(fā)者好好學(xué)習(xí)如何使用甚至是背后的設(shè)計源碼。雖然Go語言沒有如此豐富的容器類型,但也有一些基本的容器供開發(fā)者使用,接下來讓我們認(rèn)識一下這些容器類型吧
    2022-11-11

最新評論