为什么这个Go程序只能使用奇数个通道发送到通道?

时间:2018-03-26 09:23:43

标签: go concurrency

我们在学校有一项任务来修复一个有一个错误的go程序,它没有打印发送到频道的所有值。我不是要求解决方案,但是我发现了一些奇怪的东西,我无法用我对Go的知识来解释。

这是代码:

package main

import "fmt"

func main() {
    ch := make(chan int)

    go Print(ch)
    for i := 1; i <= 12; i++ {
        ch <- i
    }
    close(ch)
}

func Print(ch <-chan int) {
    for n := range ch{ 
        fmt.Println(n)
    }
}

问题是Print例程不会打印在通道上发送的所有整数,我已经设法使用waitgroup在我的解决方案中修复了这些整数。但奇怪的是,如果整数是偶数,程序将打印完全发送到通道的所有整数。所以我试着在Go Playground中运行这个程序,如果整数的数量是奇数的话,Go Playground中的程序似乎会打印所有的整数。为什么是这样?我对此有点困惑。

链接去游乐场计划:https://play.golang.org/p/-BLHvC8RomC

3 个答案:

答案 0 :(得分:1)

您必须正确同步您的计划:

package main

import (
        "fmt"
)

func main() {
        done := make(chan bool)
        ch := make(chan int)

        go Print(ch, done)
        for i := 1; i <= 12; i++ {
                ch <- i
        }
        done<-true
        <-done
}

func Print(ch chan int, done chan bool) {
        defer func(done chan bool){done<-true}(done)
        for{
                select {
                case <-done:
                        return
                case n := <-ch:
                        fmt.Println(n)
                }
        }
}

https://play.golang.org/p/e_fr2UBeyKA

答案 1 :(得分:1)

这是一个消费者 - 生产者并发模式,在Go中实现它的一种方法如下:

    $username = "accountname"
    $pwd = "accountnamePassword"
    $domain = "mydomain"
    $req = [system.Net.WebRequest]::Create($url)
    $req.Credentials = new NetworkCredential($username, $pwd, $domain);

我希望这有帮助!

答案 2 :(得分:0)

导入“时间”并在关闭后添加时间。睡眠(50000)。你有一个隐含的种族,主要是拆除程序,你的goroutine还没有完成。