Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 如何在同一循环中向通道发送和接收值?_Go_Channel_Goroutine - Fatal编程技术网

Go 如何在同一循环中向通道发送和接收值?

Go 如何在同一循环中向通道发送和接收值?,go,channel,goroutine,Go,Channel,Goroutine,以下是一个例子: func main() { c := make(chan int) i := 0 go goroutine(c) c <- i time.Sleep(10 * time.Second) } func goroutine(c chan int) { for { num := <- c fmt.Println(num) num++ time.Sleep

以下是一个例子:

func main() {
    c := make(chan int)
    i := 0

    go goroutine(c)

    c <- i
    time.Sleep(10 * time.Second)

}

func goroutine(c chan int) {
    for {
        num := <- c
        fmt.Println(num)
        num++
        time.Sleep(1 * time.Second)
        c <- num
    }
}

我做错什么了吗?

您使用了无缓冲通道,所以您的goroutine挂在c上您使用c创建了一个无缓冲通道

在无缓冲信道上,操作是对称的,即信道上的每个发送只需要一次接收,每个接收只需要一次发送。将i发送到通道中,goroutine将其接收到num中。之后,goroutine将递增的num发送到通道中,但没有人接收它

简言之:声明

c <- num
将阻止

您可以使用1缓冲通道,这应该可以工作


您的代码还有一个问题需要在main中等待10秒才能解决:您不知道goroutine何时完成。通常,在这些情况下使用sync.WaitGroup。但是:你的goroutine没有结束。习惯做法是引入一个chan结构{},在一段时间后在主goroutine中关闭,然后在worker goroutine中的两个通道上进行选择。

默认情况下,goroutine通信是同步且无缓冲的:只有在有接收者接受该值时,发送才会完成。必须有一个接收器准备从通道接收数据,然后发送方可以直接将数据移交给接收器

因此,通道发送/接收操作将阻塞,直到另一端准备就绪:

一,。通道上的发送操作会阻塞,直到同一通道有可用的接收器:如果ch上的值没有收件人,则无法在通道中放入其他值。另一种方法是:当通道不为空时,不能在ch中发送新值!因此,发送操作将等待ch再次可用

二,。在发送方可用于同一信道之前,信道的一种接收操作将被阻塞:如果信道中没有值,则接收机将被阻塞

以下示例对此进行了说明:

package main
import "fmt"

func main() {
    ch1 := make(chan int)
    go pump(ch1) // pump hangs
    fmt.Println(<-ch1) // prints only 0
}

func pump(ch chan int) {
    for i:= 0; ; i++ {
        ch <- i
    }
}

感谢您的详细解释。请注意,上一个主函数在启动第二个goroutine后返回,因此程序可能会立即退出,而不是等待非主goroutine完成。它可能是泵和接收,甚至不会被调用。
c <- num
package main
import "fmt"

func main() {
    ch1 := make(chan int)
    go pump(ch1) // pump hangs
    fmt.Println(<-ch1) // prints only 0
}

func pump(ch chan int) {
    for i:= 0; ; i++ {
        ch <- i
    }
}
func receive(ch chan int) {
    for {
        fmt.Println(<- ch)
    }
}
func main() {
    ch := make(chan int)
    go pump(ch)
    go receive(ch)
}