关闭Go频道并同步go例程

vitamike:

我无法在go中终止我的WaitGroup,因此无法退出范围循环。谁能告诉我为什么。或者是一种更好的方法来限制执行例程的数量,同时仍然可以在关闭时退出!

我看到的大多数示例都与静态类型的chan长度有关,但是由于其他过程,该通道的大小会动态调整。

示例中的打印语句(“ DONE!”)已打印,表明testValProducer打印了正确的时间,但是代码从未到达(“ --EXIT--”),这意味着wg.Wait仍以某种方式阻止。

type TestValContainer chan string

func StartFunc(){
testValContainer            := make(TestValContainer)
go func(){testValContainer <- "string val 1"}()
go func(){testValContainer <- "string val 2"}()
go func(){testValContainer <- "string val 3"}()
go func(){testValContainer <- "string val 4"}()
go func(){testValContainer <- "string val 5"}()
go func(){testValContainer <- "string val 6"}()
go func(){testValContainer <- "string val 7"}()
wg  := sync.WaitGroup{}

// limit the number of worker goroutines
for i:=0; i < 3; i++ {
    wg.Add(1)
    go func(){
        v := i
        fmt.Printf("launching %v", i)
        for str := range testValContainer{
            testValProducer(str, &wg)
        }
        fmt.Println(v, "--EXIT --")  // never called
    }()
}

wg.Wait()
close(testValContainer)

}


func get(url string){
    http.Get(url)
    ch <- getUnvisited()
}


func testValProducer(testStr string, wg *sync.WaitGroup){
    doSomething(testStr)
    fmt.Println("done !") // called
    wg.Done() // NO EFFECT??
}
reticentroot:

我可能会做这样的事情,它使一切易于遵循。我定义了一个实现信号量的结构,以控制活动的Go例程旋转的数量,并允许我在进入时从通道中进行读取。

package main

import (
    "fmt"
    "sync"
)

type TestValContainer struct {
    wg   sync.WaitGroup
    sema chan struct{}
    data chan int
}

func doSomething(number int) {
    fmt.Println(number)
}

func main() {
    //semaphore limit 10 routines at time
    tvc := TestValContainer{
        sema: make(chan struct{}, 10),
        data: make(chan int),
    }

    for i := 0; i <= 100; i++ {
        tvc.wg.Add(1)
        go func(i int) {
            tvc.sema <- struct{}{}
            defer func() {
                <-tvc.sema
                tvc.wg.Done()
            }()

            tvc.data <- i
        }(i)
    }
    // wait in the background so that waiting and closing the channel dont
    // block the for loop below
    go func() {
        tvc.wg.Wait()
        close(tvc.data)
    }()
    // get channel results
    for res := range tvc.data {
        doSomething(res)
    }

}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章