golang:协程和频道的奇怪问题

时间:2017-03-09 21:13:22

标签: go channel coroutine

我写了一个测试代码,但不明白我为什么会得到这个结果。

我的sub()应根据频道值

更新或返回counter
send 1 = counter++
send 0 = return counter

我开始了10个例程con()。 他们应该简单地将多个1发送到频道(这个增加计数器)
我等待1秒并将0发送到频道。我应该得到什么价值?

我想首先,我得到一个“随机”值, 但我得到100000(好10x 10000比1秒快)

现在我改变了

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

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

现在我的返回值是1

为什么!?

现在取消注释fmt.Println(counter)中的main()。 正如你看到计数器工作并有这个“随机”数字

package main

import (
    "fmt"
    "time"
)

var ch chan int = make(chan int)
var counter int

func main() {
    go sub()

    for i:=0; i < 10; i++ { //change to 10000
        go con()
    }

    time.Sleep(1000 * time.Millisecond)

    ch <- 0
    fmt.Println(<- ch)
    //fmt.Println(counter) //uncomment this
}

func sub() {
    for c := range ch {
        if c == 0 { ch <- counter }
        if c == 1 { counter++ }
    }
}

func con() {
    for i := 0; i < 10000; i++ {
        ch <- 1
    }
}

1 个答案:

答案 0 :(得分:0)

有2个频道,这项工作:

package main

import (
    "fmt"
    "time"
)

var ch chan int = make(chan int)
var ch2 chan int = make(chan int)
var counter int

func main() {
    go sub()

    for i:=0; i < 10000; i++ { //change to 10000
        go con()
    }

    time.Sleep(1000 * time.Millisecond)

    ch2 <- 0
    fmt.Println(<- ch2)
    //fmt.Println(counter) //uncomment this
}

func sub() {
    for ;; {
        select {
        case <- ch:
            counter++
        case <- ch2:
            ch2 <- counter
        }
    }
}

func con() {
    for i := 0; i < 10000; i++ {
        ch <- 1
    }
}