英文:
why go routine only prints one value when sent through channel
问题
我有以下代码:
import (
"fmt"
)
func access(ch chan int) {
for elem := range ch {
fmt.Println(elem) // 只打印一个值
}
fmt.Println(<-ch) // 打印该值
fmt.Println(<-ch) // 不打印
}
func main() {
ch := make(chan int)
go access(ch)
ch <- 55 // 阻塞主程序
ch <- 56 // 这个值永远不会打印
fmt.Println("Hello, World!")
}
为什么只有通过通道发送的第一个值被打印出来,而不是其他的值,即使使用了无缓冲通道和for循环?
如果我使用for循环发送值,它就可以工作。
arr := []int{1, 1, 1, 1, 1}
for elem := range arr {
ch <- elem
}
这里还有一个谜,如果我添加三个值发送到ch,所有的值都会在access函数中打印出来。这有点奇怪...
func access(ch chan int) {
/*
for elem := range ch {
fmt.Println(elem)
}
*/
// 所有的打印
fmt.Println(<-ch)
fmt.Println(<-ch)
fmt.Println(<-ch)
}
func main() {
go access(ch)
ch <- 55
ch <- 56
ch <- 57
}
英文:
I have following code
import (
"fmt"
)
func access(ch chan int) {
for elem := range ch {
fmt.Println(elem) // prints only one as well
}
fmt.Println(<-ch) // prints the value
fmt.Println(<-ch) // doesn't print
}
func main() {
ch := make(chan int)
go access(ch)
ch <- 55 // blocks the main routine
ch <- 56 // this value never prints
fmt.Println("Hello, World!")
}
Why only the first value sent through channel gets printed not the other one ,even with for loop ,inspite of using unbuffered channel
If I use a for loop to send values it works
arr:=[]int{1, 1, 1, 1, 1}
for elem := range arr {
ch<-elem
}
Here is another mystery ,if I add three values sending to ch.All values gets printed in the access function .this is bit strange .....................
func access(ch chan int){
/*
for elem := range ch {
fmt.Println(elem)
}
*/
// All prints
fmt.Println(<-ch)
fmt.Println(<-ch)
fmt.Println(<-ch)
}
func main() {
go access(ch)
ch<-55
ch<-56
ch<-57
}
答案1
得分: 1
发送第一个值后,main
协程被第二次发送操作阻塞,直到第一个值被处理,这就是为什么第一个数字会被打印出来,即使在主协程上没有等待的情况下。(我不确定这种行为是否由调度器保证,很可能不是。)但是在发送第二个值后,main
立即退出,没有给其他协程完成的机会。你可能想要先等待协程完成:
package main
import (
"fmt"
"sync"
)
func access(ch chan int) {
fmt.Println(<-ch) // 打印值
fmt.Println(<-ch) // 不打印
}
func main() {
ch := make(chan int)
var wg sync.WaitGroup
wg.Add(1)
go func() {
access(ch)
wg.Done()
}()
ch <- 55
ch <- 56
wg.Wait()
fmt.Println("Hello, World!")
}
英文:
After sending the first value, the main
goroutine is blocked by the second send operation, until the first one is processed, that's why the first number is printed even without waiting on the main side. (I'm not sure that this behavior is guaranteed by the scheduler, most likely, not.) But after sending the second value, main
exits immediately, without giving the other goroutine a chance to finish. You may want to wait for the goroutine to complete first:
package main
import (
"fmt"
"sync"
)
func access(ch chan int) {
fmt.Println(<-ch) // prints the value
fmt.Println(<-ch) // doesn't print
}
func main() {
ch := make(chan int)
var wg sync.WaitGroup
wg.Add(1)
go func() {
access(ch)
wg.Done()
}()
ch <- 55
ch <- 56
wg.Wait()
fmt.Println("Hello, World!")
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论