第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

將通道從無(wú)緩沖更改為緩沖會(huì)阻止 goroutine 運(yùn)行

將通道從無(wú)緩沖更改為緩沖會(huì)阻止 goroutine 運(yùn)行

Go
動(dòng)漫人物 2022-11-08 15:21:45
這是一個(gè)在 goroutine 中使用通道和選擇的練習(xí)。如果斷開連接通道更改為緩沖通道,則 goroutine 根本不會(huì)運(yùn)行。為什么從無(wú)緩沖通道更改為緩沖通道會(huì)阻止運(yùn)行 goroutine?func SelectDemo(wg *sync.WaitGroup) {    messageCh := make(chan int, 10)    disconnectCh := make(chan struct{})    //  go routine won't run if channel is buffered    //disconnectCh := make(chan struct{}, 1)    defer close(messageCh)    defer close(disconnectCh)    go func() {        fmt.Println("  goroutine")        wg.Add(1)        for {            select {            case v := <-messageCh:                fmt.Println(v)            case <-disconnectCh:                fmt.Println("  disconnectCh")                //  empty the buffered channel before exiting                for {                    select {                    case v := <-messageCh:                        fmt.Println(v)                    default:                        fmt.Println("  disconnection, return")                        wg.Done()                        return                    }                }            }        }    }()    fmt.Println("Sending ints")    for i := 0; i < 10; i++ {        messageCh <- i    }    fmt.Println("Sending done")    disconnectCh <- struct{}{}}這是從 main 調(diào)用函數(shù)的代碼。我使用等待組來確保 goroutine 在程序退出之前完成:wg := sync.WaitGroup{}ch09.SelectDemo(&wg)wg.Wait()
查看完整描述

2 回答

?
一只萌萌小番薯

TA貢獻(xiàn)1795條經(jīng)驗(yàn) 獲得超7個(gè)贊

該代碼邏輯有許多缺陷 - 其中一些是:

1- 由于messageCh被緩沖,此代碼沒有阻塞:


    for i := 0; i < 10; i++ {

        messageCh <- i

    }

所以下一個(gè)代碼在快速運(yùn)行路徑中:


disconnectCh <- struct{}{}

如果您進(jìn)行disconnectCh緩沖,則此行也不會(huì)阻塞運(yùn)行,并且該SelectDemo函數(shù)可能會(huì)在運(yùn)行wg.Add(1).


所以:你必須把:


wg.Add(1)


go func() {

2-即使使用wg.Add(1)之前的go func() { 代碼-

您也有:


    defer close(messageCh)

    defer close(disconnectCh)

這將在函數(shù)返回時(shí)關(guān)閉兩個(gè)通道SelectDemo這select是一個(gè)隨機(jī)選擇,因?yàn)閮蓚€(gè)通道都準(zhǔn)備好了:


fmt.Println("  goroutine")

        for {

            select {

            case v := <-messageCh:

                fmt.Println(v)

            case <-disconnectCh:

第二個(gè)選擇很可能是:


                for {

                    select {

                    case v := <-messageCh:

                        fmt.Println(v)

                    default:

                        fmt.Println("  disconnection, return")

                        wg.Done()

                        return

                    }

                }

將在messageCh關(guān)閉后0永遠(yuǎn)運(yùn)行,在讀取通道數(shù)據(jù)后永遠(yuǎn)返回:


case v := <-messageCh:

    fmt.Println(v)


查看完整回答
反對(duì) 回復(fù) 2022-11-08
?
犯罪嫌疑人X

TA貢獻(xiàn)2080條經(jīng)驗(yàn) 獲得超4個(gè)贊

程序執(zhí)行速度快


訪問網(wǎng)址:https ://pkg.go.dev/sync#WaitGroup.Add


請(qǐng)注意,當(dāng)計(jì)數(shù)器為零時(shí)發(fā)生的具有正增量的調(diào)用必須在等待之前發(fā)生。具有負(fù)增量的調(diào)用或具有正增量的調(diào)用在計(jì)數(shù)器大于零時(shí)開始,可能隨時(shí)發(fā)生。通常這意味著對(duì) Add 的調(diào)用應(yīng)該在創(chuàng)建 goroutine 的語(yǔ)句或其他要等待的事件之前執(zhí)行。如果重用 WaitGroup 來等待多個(gè)獨(dú)立的事件集,則必須在所有先前的 Wait 調(diào)用都返回后發(fā)生新的 Add 調(diào)用。請(qǐng)參閱 WaitGroup 示例。


func SelectDemo(wg *sync.WaitGroup) {


    messageCh := make(chan int, 10)

    disconnectCh := make(chan struct{}, 1)

    //  go routine won't run if channel is buffered

    //disconnectCh := make(chan struct{}, 1)


    wg.Add(1)


    defer close(messageCh)

    defer close(disconnectCh)

    go func() {

        fmt.Println("  goroutine")

        for {

            select {

            case v := <-messageCh:

                fmt.Println(v)

            case <-disconnectCh:

                fmt.Println("  disconnectCh")

                //  empty the buffered channel before exiting


                fmt.Println("  disconnection, return")

                wg.Done()

                return

            }

        }

    }()


    fmt.Println("Sending ints")

    for i := 0; i < 10; i++ {

        messageCh <- i

    }


    //Delay sending exit signal

    time.Sleep(3 * time.Second)


    fmt.Println("Sending done")

    disconnectCh <- struct{}{}

}


我修改了你的代碼


再試一次?。?!


查看完整回答
反對(duì) 回復(fù) 2022-11-08
  • 2 回答
  • 0 關(guān)注
  • 120 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)