缓存channel使用for-range?

bvaccc · 2016-12-23 07:47:04 · 1727 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2016-12-23 07:47:04 的主题,其中的信息可能已经有所发展或是发生改变。

代码如下:

package main

import (
    "fmt"
    "runtime"
)

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    c := make(chan bool, 10)
    for i := 0; i < 10; i++ {
        go Go(c, i)
    }
    for i := 0; i < 10; i++ { //如何使用`for-range`循环实现?
        <-c
    }
}

func Go(c chan bool, index int) {
    a := 0
    for i := 0; i < 10000000; i++ {
        a += i
    }
    fmt.Println(index, a)

    c <- true
}

求解。


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1727 次点击  
加入收藏 微博
9 回复  |  直到 2016-12-24 06:52:15
stevewang
stevewang · #1 · 8年之前

这里不适合用range,因为需要配合close,但是找不到合适的地方去close channel

abin
abin · #2 · 8年之前

package main

import ( "fmt" "runtime" )

func main() { runtime.GOMAXPROCS(runtime.NumCPU()) cs := make([]chan bool, 10) for i := 0; i < 10; i++ { cs[i] = make(chan bool, 1) go Go(cs[i], i) } for _, c := range cs { <-c } }

func Go(c chan bool, index int) { a := 0 for i := 0; i < 10000000; i++ { a += i } fmt.Println(index, a)

c <- true

}

改成slice试试?

abin
abin · #3 · 8年之前

D59AFC09-6D42-430E-A74F-7332FA089F92.png

bvaccc
bvaccc · #4 · 8年之前

#2 楼 @abin 谢谢,是个办法

bvaccc
bvaccc · #5 · 8年之前

#1 楼 @stevewang 明白了,谢谢

jmzwcn
jmzwcn · #6 · 8年之前

for len(queue) > 0 { value := <-queue fmt.Println(value) }

dophin
dophin · #7 · 8年之前
package main

import (
    "fmt"
    "runtime"
    "sync"
)

var wg sync.WaitGroup

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    c := make(chan bool, 10)
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go Go(c, i)
    }

    wg.Wait()
    close(c)

    for i := range c { //如何使用`for-range`循环实现?
        // use i
        fmt.Println(i)
    }
}

func Go(c chan bool, index int) {
    defer wg.Done()
    a := 0
    for i := 0; i < 10000000; i++ {
        a += i
    }
    fmt.Println(index, a)

    c <- true
}
alex_023
alex_023 · #8 · 8年之前

还是七楼优雅,利用了close的特性。如果wg的代码放在一起,而不是“defer wg.Done()"放在Go函数中,就更符合习惯。需调整部分:

//...
for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            Go(c, i)   // 内部的Defer ..,需要删除
            wg.Done()
        }()
    }
    wg.Wait()
    close(c)
//...
huangxianghan
huangxianghan · #9 · 8年之前

看了下你的代码,我觉得你的代码的意图是,创建一个bool的chan 每个线程结束通知这个通道。 然后再通过遍历这个通道来达到等待所有线程都执行结束的目的。 但是完全不需要用到通道。直接用WaitGroup就行了。 不知道你是否这个意图。至少你代码展现是这个意图。 以下使用WaitGroup的例子。

package main

import (
    "fmt"
    "sync"
)

func main() {

    //如果想用和cpu同等数量的线程,这句根本不需要,go默认就是。
    //runtime.GOMAXPROCS(runtime.NumCPU())

    var wg sync.WaitGroup

    for i := 0; i < 10; i++ {
        wg.Add(1) 
        go Go(&wg, i)
    }

    wg.Wait()
}

func Go(wg *sync.WaitGroup, index int) {
    //defer 的作用不单单是结束才运行,它是保证函数出错了也运行的机制。
    //但对性能有影响,如果这函数永远不会发生运行时错误,最好加到末尾。
    defer wg.Done() 

    a := 0
    for i := 0; i < 10000000; i++ {
        a += i
    }
    fmt.Println(index, a)
    //wg.Done() 
}
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传