在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/GO/ golang channel 怎么判斷是否讀取完成?

golang channel 怎么判斷是否讀取完成?

    r := make(chan int)
    for n := 0; n < 100000; n++ {
        go func(x int, r chan int) {
                if x%3 == 0 && x%23 == 0{
                    r <- x
                }
        }(n, r)
    }

for i := range r {
    println(i) 
} 

上面的代碼報(bào)錯(cuò)。

而我又不知道channel 的個(gè)數(shù),那么我怎么知道,什么時(shí)候,并發(fā)執(zhí)行結(jié)束了呢?

求指教

回答
編輯回答
兔囡囡

大神,指教啊,誨人不倦啊,。。。。。

2018年8月20日 10:31
編輯回答
有點(diǎn)壞

預(yù)先不知道channel里消息會(huì)有多少的話,我認(rèn)為可以通過判斷超時(shí)的方式來進(jìn)行判斷
因?yàn)檫@里定義的是無緩沖channel,所以第一個(gè)for循環(huán)必須啟一個(gè)協(xié)程,要不然就阻塞在那里了

func main(){
    r := make(chan int)
    go func() {
        for n := 0; n < 100000; n++ {
            go func(x int, r chan int) {
                if x%3 == 0 && x%23 == 0{
                    r <- x
                }
            }(n, r)
        }
    }()

    for{
        select {
            case i := <- r:
                fmt.Println(i)
            case <- time.After(time.Second*3):
                fmt.Printf("time out")
                goto out
        }
    }
out:
    fmt.Printf("end")
}

也可以加一個(gè)chan來判斷結(jié)束,不過并沒有驗(yàn)證嚴(yán)謹(jǐn)性,僅供參考

func main(){
    r := make(chan int)
    quit := make(chan int)
    go func() {
        for n := 0; n < 100000; n++ {
            go func(x int, r chan int) {
                if x%3 == 0 && x%23 == 0{
                    r <- x
                }
            }(n, r)
        }
        quit <- 1
    }()

    for{
        select {
            case i := <- r:
                fmt.Println(i)
            case <- quit:
                fmt.Println("quit")
                goto out
        }
    }
out:
    fmt.Printf("end")
}
2017年8月10日 18:59
編輯回答
玄鳥

首先題目中只有一個(gè)channel
所有啟動(dòng)的goroutine作為發(fā)送者,主程序作為接收者。他們共享了這一個(gè)channel

在go關(guān)鍵字啟動(dòng)的所有的goroutine發(fā)送完畢后,即會(huì)退出。
只剩下主程序的for...range循環(huán)還在試圖從channel接收數(shù)據(jù),因此造成deadlock報(bào)錯(cuò)。

解決問題:只需要所有的goroutinue(發(fā)送端)執(zhí)行完畢后,關(guān)閉channel。

close(r)

何時(shí)所有的goroutinue執(zhí)行完畢就需要另行判斷了

2017年8月8日 23:00
編輯回答
赱丅呿
import "sync"
    
func main() {
    rNum := 100000
    r := make(chan int, rNum)
    var wg sync.WaitGroup
    for n := 0; n < rNum; n++ {
        wg.Add(1)
        go func(x int, r chan int) {
            defer wg.Done()
            if x%3 == 0 && x%23 == 0 {
                r <- x
            }
        }(n, r)
    }

    wg.Wait()
    close(r)                           
    for i := range r {
        println(i)
    }
}
2018年8月7日 17:52
編輯回答
故人嘆
package main

import (
    "sync"
)

func main() {

    wait := sync.WaitGroup{}
    r := make(chan int)
    for n := 0; n < 100000; n++ {
        wait.Add(1)
        go func(x int, r chan int) {
            defer wait.Done()
            if x%3 == 0 && x%23 == 0 {
                r <- x
            }
        }(n, r)
    }
    go func() {
        wait.Wait()
        close(r)
    }()

    for i := range r {
        println(i)
    }

}
2018年8月6日 16:29