去编程语言代码错误

时间:2011-11-22 15:46:18

标签: go

我尝试在GO中编写一个简单的代码,其中两个go例程(Send和Receive)发送彼此的整数。我给出下面的代码。任何人都可以帮助我为什么这个程序的输出是[无输出]。有什么愚蠢的错误(对不起,我是GO的新手)?

package main

func Send (in1 <-chan int, out1 chan<- int) {

                i := 2 
        out1 <- i 
    print(i, "\n")
}

func Receive (in <-chan int, out chan<- int) {

        i := <-in 
        print(i, "\n")
        out <- i 
}


func main() {

       for i := 0; i < 10; i++ {
        ch1 := make(chan int)
        ch := make(chan int) 
            go Send (ch1 , ch)
        go Receive (ch , ch1)
        ch = ch1
        ch1 = ch
        }

}

2 个答案:

答案 0 :(得分:2)

这个怎么样:

package main

func Send (ch chan<- int) {
    for i := 0; i < 10; i++ {
      print(i, " sending\n")
      ch <- i
    }
}

func Receive (ch <-chan int) {
    for i := 0; i < 10; i++ {
        print(<-ch, " received\n")
    }
}

func main() {
   ch := make(chan int)
   go Receive(ch)
   Send(ch)
}

当我在golang.org上运行它时的输出是:

0 sending
0 received
1 sending
2 sending
1 received
2 received
3 sending
4 sending
3 received
4 received
5 sending
6 sending
5 received
6 received
7 sending
8 sending
7 received
8 received
9 sending

我不确定为什么9从未收到过。应该有一些方法来睡眠主线程,直到接收goroutine完成。此外,接收者和发送者都知道他们将发送10个号码是不优雅的。其中一个goroutines应该在对方完成工作时关闭。我不知道该怎么做。

<强> EDIT1:

这是一个具有两个通道的实现,并且go例程在彼此之间来回发送inlet。一个被指定为响应者,它只在收到int后发送和int。响应者只是将两个加到他收到的int中,然后将其发回。

package main

func Commander(commands chan int, responses chan int) {
    for i := 0; i < 10; i++ {
      print(i, " command\n")
      commands <- i
      print(<-responses, " response\n");
    }
    close(commands)
}

func Responder(commands chan int, responses chan int) {
    for {
        x, open := <-commands
        if !open {
            return;
        }
        responses <- x + 2
    }
}

func main() {
   commands := make(chan int)
   responses := make(chan int)
   go Commander(commands, responses)
   Responder(commands, responses)
}

我在golang.org上运行时的输出是:

0 command
2 response
1 command
3 response
2 command
4 response
3 command
5 response
4 command
6 response
5 command
7 response
6 command
8 response
7 command
9 response
8 command
10 response
9 command
11 response

答案 1 :(得分:2)

David Grayson的修复工作,但是为什么9并不总是被收到的解释不适合评论!

当发送goroutine在通道上发送值时,它会阻塞,直到接收goroutine接收到它。那时,它已被解锁。 go调度程序几乎可以在它给接收goroutine一个机会打印任何东西之前立即从main返回。如果将GOMAXPROCS设置为大于1的值,则这种情况发生的频率较低,因为接收goroutine在主goroutine处于活动状态时不会阻塞。

如果你想在完成所有goroutine之前停止main返回,你可以从Receive()返回一个频道,如下所示:

package main

import "fmt"

func Send(ch chan<- int) {
    for i := 0; i < 10; i++ {
        fmt.Println(i, " sending")
        ch <- i
    }
    close(ch)
}

func Receive(ch <-chan int) (<-chan bool) {
    done := make(chan bool)
    go func() {
        for {
            i, ok := <-ch
            if !ok {
                break
            }
            fmt.Println(i, " received")
        }
        done <- true
    }()
    return done
}

func main() {
    ch := make(chan int)
    d := Receive(ch)
    Send(ch)
    _ = <-d
}

至于为什么你的输出在你的原始例子中是空的:你制作两个goroutines,因此main完全解锁,所以它只返回并退出程序!我也确实犯了这个错误,但是运行时只加入主goroutine,而不是像所期望的那样与所有goroutine结合。