1 回答
TA贡献1799条经验 获得超6个赞
声誉不足,无法发表评论。因此,为了代替注释,下面是代码的替代版本:
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
const sizeLetters = 12
func detectX(ch2 chan int, j int, letters [sizeLetters]string) {
if letters[j] == "x" {
ch2 <- j
}
}
func main() {
ch1 := make(chan int)
ch2 := make(chan int)
letters := [sizeLetters]string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"}
threads := 4
wg.Add(threads)
for i := 0; i < threads; i++ {
go func() {
for {
j, ok := <-ch1
if !ok {
wg.Done()
return
}
detectX(ch2, j, letters)
}
}()
}
// Use a goroutine to close ch2. It is only safe to do this
// after all the other goroutines have exited.
go func() {
wg.Wait()
close(ch2)
}()
for i := 0; i < sizeLetters; i++ {
ch1 <- i // add i to the queue
}
close(ch1)
if k, ok := <-ch2; ok && k != -1 { //when exist
fmt.Println("X exist in position:", k)
} else {
fmt.Println("X doesn´t exist")
}
}
它仍然有一些与数据相关的问题(除非保证数组不包含重复项):letters
也就是说,如果数组中有多个,则 goroutine 不会全部退出。也就是说,不会耗尽 。
"x"
main()
ch2
如果值的数量与值一样多,则代码将在顶层循环中死锁,因为写入将耗尽未阻塞的 goroutine 来使用它们。
threads
"x"
for
main()
ch1
如果您知道数组中可能有多少个值,则可以使通道深度为:。这将允许所有 goroutines 退出,但可能仍包含未拖累的数据。
"x"
letters
ch2
ch2 := make(chan int, depth)
ch2
- 1 回答
- 0 关注
- 59 浏览
添加回答
举报