如何解决所有 goroutine 都是睡眠死锁
模拟我的真正问题,我有这个代码。
基本上,数组“字母”的每个元素及其索引都被发送到一个 goroutine 以将它与“x”进行比较,然后它通过通道发送响应。
我的想法是它在“x”个线程上运行,在实际情况下我使用 8 个线程。
package main
import (
"strconv"
"sync"
)
var wg sync.WaitGroup
const sizeLetters = 12
func detectX(ch2 chan int,j int,letters [sizeLetters]string) {
if letters[j] == "x" {
ch2 <- j
}else{
ch2 <- -1
}
}
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()
}
detectX(ch2,j,letters)
}
}()
}
for i := 0; i < sizeLetters; i++ {
ch1<-i // add i to the queue
}
k,ok := <-ch2 //k contains the position of X,if exist
if !ok {
wg.Done()
}
if k != -1 { //when exist
println("X exist in position: " + strconv.Itoa(k))
}
println("X doesn´t exist")
close(ch2)
close(ch1)
wg.Wait()
}
解决方法
声誉不足,无法发表评论。因此,代替注释,这里是代码的替代版本:
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
数组不包含重复项):
- 也就是说,如果数组中有多个
"x"
,goroutines不会全部退出。也就是说,main()
不会消耗ch2
。 - 如果有多达
threads
"x"
个值,那么代码将在for
中的顶级main()
循环中死锁,因为写入 {{1}将耗尽未阻塞的 goroutine 来使用它们。- 如果您知道
ch1
数组中可能有多少个"x"
值,您可以使letters
通道如此深:ch2
。这将允许所有 goroutine 退出,但ch2 := make(chan int,depth)
仍可能包含未排出的数据。
- 如果您知道
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。