【发布时间】:2021-06-30 12:40:01
【问题描述】:
模拟我的真正问题我有这个代码。
基本上,数组“字母”的每个元素及其索引都被发送到一个 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()
}
【问题讨论】:
-
make(chan int)创建一个阻塞通道。只有在与并发读取匹配时,对它的写入才会完成。当detectX()首次写入ch2时,没有人从中读取,因为main()仍在尝试将值推送到ch1。您还尝试将 12 个值写入ch2,但只尝试读取一次。 -
@Zyl 我必须在我的代码中更正它,也许是在上下文中,但我仍然不知道如何很好地实现它。当检测到或未检测到 X 时,您将如何从 detectX 发送响应。
-
context存在于取消信号中,因此在这里有意义:您希望在找到结果后停止工作。另外,除非您确实有结果,否则我不会写入 ch2 。我也会使 ch2 缓冲,即使用make(chan int, 1)。我还会通过defer调用wg.Done()。现在你打电话给detectX(),即使你没有从ch1得到任何价值。然后wg.Wait()在完成写入 ch1 之后,而不是在main()的末尾。也许尝试一些简单的练习会有所帮助。