英文:
Is it one channel ops affect another channel ops
问题
我写了这段简单的代码,试图了解通道的工作原理。如果在发送通道b之后发送通道c,最后一个例程中的通道不会被发送。
我有两个通道,通道c用于将通道b分割为4个切片的部分。
package main
import (
"fmt"
"strconv"
)
func runner(idx int, c chan []int, b chan []int) {
var temp []int
fmt.Println("runner " + strconv.Itoa(idx))
bucket := <-b
for k, v := range bucket {
if v != 0 {
temp = append(temp, v)
bucket[k] = 0
}
if len(temp) == 5 {
break
}
}
// 如果在发送通道b之后发送通道c,奇怪的条件下,最后一个通道不会被发送
b <- bucket
c <- temp
// 如果在发送通道c之后发送通道b,这样是正确的
// c <- temp
// b <- bucket
}
func printer(c chan []int) {
for {
select {
case msg := <-c:
fmt.Println(msg)
//time.Sleep(time.Second * 1)
}
}
}
func main() {
c := make(chan []int, 5)
bucket := make(chan []int)
go runner(1, c, bucket)
go runner(2, c, bucket)
go runner(3, c, bucket)
go runner(4, c, bucket)
bucket <- []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
go printer(c)
var input string
fmt.Scanln(&input)
}
希望对你有帮助!
英文:
I made this simple code, trying to know how's channel works, somehow if channel c is sent after channel b is sent, channel in last routine is not being sent,
I have 2 channel, channel c is for spliting channel b to 4 part of slice.
package main
import (
"fmt"
"strconv"
)
func runner(idx int, c chan []int, b chan []int) {
var temp []int
fmt.Println("runner " + strconv.Itoa(idx))
bucket := <-b
for k, v := range bucket {
if v != 0 {
temp = append(temp, v)
bucket[k] = 0
}
if len(temp) == 5 {
break
}
}
//Strange condition if channel c is sent after channel b is sent,
//somehow the last chan is not being sent
b <- bucket
c <- temp
//this is right if channel b is sent after channel c is sent
//c <- temp
//b <- bucket
}
func printer(c chan []int) {
for {
select {
case msg := <-c:
fmt.Println(msg)
//time.Sleep(time.Second * 1)
}
}
}
func main() {
c := make(chan []int, 5)
bucket := make(chan []int)
go runner(1, c, bucket)
go runner(2, c, bucket)
go runner(3, c, bucket)
go runner(4, c, bucket)
bucket <- []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
go printer(c)
var input string
fmt.Scanln(&input)
}
答案1
得分: 3
bucket := make(chan []int)
你的 b
通道的容量是0。这意味着每当你向该通道发送数据时,通道立即变满,并且会阻塞直到接收者读取通道。
当只剩下一个运行程序时,没有人会调用 bucket := <-b
来读取最后一个桶,因此最后一个 goroutine 将永远卡在 b <- bucket
这一行上,因此下一行的 c <- temp
对于这个最后一个 goroutine 永远不会被调用。
英文:
bucket := make(chan []int)
Your b
channel's capacity is 0. This means whenever you send something to this channel, the channel is full immediately and will block until a receiver reads the channel.
When there is only one runner left, no one is going to call bucket := <-b
to read the last bucket, thus this last goroutine is stuck forever on the b <- bucket
line, and thus the next line c <- temp
will never be called for this last goroutine.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论