戈朗 : strange issue with coroutines and channels

标签 go channel coroutine

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

我的 sub() 应该根据 channel 值更新或返回 counter

send 1 = counter++
send 0 = return counter

我启动了 10 个 go 例程 con()。 他们应该简单地发送许多 1 到 channel (这个增加计数器)
我等待 1 秒并将 0 发送到 channel 。我应该获得什么值(value)?

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

现在我变了

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

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

现在我的返回值是1

为什么!?

现在取消注释 main() 中的 fmt.Println(counter)。 如您所见,计数器工作并具有这个“随机”数字

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
    }
}

最佳答案

有 2 个 channel ,这项工作:

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
    }
}

关于戈朗 : strange issue with coroutines and channels,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42705505/

相关文章:

go - 更正 Go/RabbitMQ 方法以 "pop"队列中的一条消息?

google-app-engine - AppEngine 的 datastore.Get() 是否不验证所请求 key 的命名空间?

go - 如何列出 Alexa for Business 的联系人?

go - 选择忽略慢的情况?

pointers - 在 Go Lang 中通过 channel 传递指针

android - 多次调用分页库中的回调

android - StrictMode.detectNetwork/Disk 是否仍然适用于协程世界?

multithreading - 用户级线程和协程有什么区别?

go - 对 Goroutines 的 channel 参数感到困惑

Go range over channel 死锁问题,我应该关闭 channel 吗?