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

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

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

高能預(yù)警

本文包含演示部分,請(qǐng)讀者自行copy代碼編譯體驗(yàn)。

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

正文

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

問題演示:

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

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

可能有些讀者會(huì)想到,我直接加個(gè)死循環(huán)在下面,讓主函數(shù)不退出不就行啦?博主表示十分贊同,因?yàn)椴┲骶褪遣捎眠@個(gè)方法,導(dǎo)致服務(wù)器跑滿CPU從而不停的告警。

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

    for {
        time.Sleep(time.Second)
    }

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

解決辦法演示

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

先上代碼:

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()方法使信號(hào)將傳入c。如果沒有提供信號(hào),所有傳入的信號(hào)將被中繼到c。

  • 這里我們創(chuàng)建了一個(gè)os.Signal類型的管道。當(dāng)管道為空的時(shí)候,讀管道操作“<-”會(huì)阻塞住,直到我們向進(jìn)程發(fā)送一個(gè)信號(hào)(例如 Ctrl+C),才會(huì)繼續(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() 不會(huì)等待工作停止。

  • 這也是一個(gè)十分優(yōu)雅的辦法,我們創(chuàng)建一個(gè)可以終止的上下文——context.WithCancel(),并在go routine執(zhí)行完畢時(shí)調(diào)用其返回的CancelFunc() 方法,即表示該上下文已經(jīng)結(jié)束了。而在這之前,我們會(huì)使用<-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)建一個(gè)WaitGroup{}對(duì)象,然后調(diào)用Add()方法,在里面?zhèn)魅胛覀兘酉聛頃?huì)創(chuàng)建的go routine的數(shù)量,每當(dāng)我們執(zhí)行完一個(gè)go routine時(shí),調(diào)用一次Done()方法,使得正執(zhí)行的go routine的數(shù)量減一,當(dāng)減到0時(shí),Wait()方法將不再等待(阻塞),使main函數(shù)繼續(xù)向下執(zhí)行。

小結(jié)

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

總結(jié)

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

相關(guān)文章

  • 使用Go語言進(jìn)行條件編譯的示例代碼

    使用Go語言進(jìn)行條件編譯的示例代碼

    Go的條件編譯主要通過構(gòu)建標(biāo)簽(build?tags)和構(gòu)建約束(build?constraints)來實(shí)現(xiàn),這些標(biāo)簽和約束可以讓我們針對(duì)不同的操作系統(tǒng)、架構(gòu)或特定條件編寫特定代碼,本文給大家介紹了如何使用Go語言進(jìn)行條件編譯,需要的朋友可以參考下
    2024-06-06
  • 一文了解Go語言中編碼規(guī)范的使用

    一文了解Go語言中編碼規(guī)范的使用

    這篇文章主要介紹了一文了解Go語言中編碼規(guī)范的使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • Golang實(shí)現(xiàn)獲取與解析命令行參數(shù)

    Golang實(shí)現(xiàn)獲取與解析命令行參數(shù)

    這篇文章主要為大家詳細(xì)介紹了Golang如何實(shí)現(xiàn)獲取與解析命令行參數(shù),文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的小伙伴可以參考一下
    2024-01-01
  • 詳解MongoDB?Go?Driver如何記錄日志

    詳解MongoDB?Go?Driver如何記錄日志

    這篇文章主要為大家介紹了MongoDB?Go?Driver如何記錄日志詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • Go語言中配置實(shí)現(xiàn)Logger日志的功能詳解

    Go語言中配置實(shí)現(xiàn)Logger日志的功能詳解

    當(dāng)我們正式開發(fā)go程序的時(shí)候,就會(huì)發(fā)現(xiàn)記錄程序日志已經(jīng)不是fmt.print這么簡單了,所以我們需要專門的去存儲(chǔ)日志文件,這篇文章主要介紹了在Go語言中配置實(shí)現(xiàn)Logger日志的功能,感興趣的同學(xué)可以參考下文
    2023-05-05
  • golang-redis之sorted set類型操作詳解

    golang-redis之sorted set類型操作詳解

    這篇文章主要介紹了golang-redis之sorted set類型操作詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 一文搞懂Golang文件操作增刪改查功能(基礎(chǔ)篇)

    一文搞懂Golang文件操作增刪改查功能(基礎(chǔ)篇)

    這篇文章主要介紹了一文搞懂Golang文件操作增刪改查功能(基礎(chǔ)篇),Golang 可以認(rèn)為是服務(wù)器開發(fā)語言發(fā)展的趨勢之一,特別是在流媒體服務(wù)器開發(fā)中,已經(jīng)占有一席之地,今天我們不聊特別深?yuàn)W的機(jī)制和內(nèi)容,就來聊一聊 Golang 對(duì)于文件的基本操作
    2021-04-04
  • 使用golang實(shí)現(xiàn)一個(gè)MapReduce的示例代碼

    使用golang實(shí)現(xiàn)一個(gè)MapReduce的示例代碼

    這篇文章主要給大家介紹了關(guān)于如何使用golang實(shí)現(xiàn)一個(gè)MapReduce,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-09-09
  • Golang干貨分享之利用AST實(shí)現(xiàn)AOP功能

    Golang干貨分享之利用AST實(shí)現(xiàn)AOP功能

    本文主要是一個(gè)純干貨分享,主要介紹了Golang如何利用AST實(shí)現(xiàn)AOP功能,文中的示例代碼簡潔易懂,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-04-04
  • goland配置自動(dòng)注釋的實(shí)現(xiàn)

    goland配置自動(dòng)注釋的實(shí)現(xiàn)

    本文主要介紹了goland配置自動(dòng)注釋的實(shí)現(xiàn),文中通過圖文示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08

最新評(píng)論

五大连池市| 永春县| 鄂伦春自治旗| 娱乐| 桐乡市| 旅游| 琼海市| 武穴市| 准格尔旗| 兴山县| 左云县| 正安县| 金寨县| 姚安县| 肥东县| 汨罗市| 潞城市| 滦平县| 天台县| 广南县| 鲁甸县| 沁水县| 山西省| 奉贤区| 杭州市| 敦化市| 六安市| 信宜市| 西乌珠穆沁旗| 旬邑县| 西昌市| 平昌县| 中方县| 桓台县| 福建省| 桐城市| 沽源县| 大邑县| 盖州市| 吉林省| 芒康县|