我正在研究一个示例程序,以使用具有多个通道的goroutine打印1至100之间的奇数和偶数和。
您可以找到我的代码
输出
req = http.post<MyResponse>(url, [{...}])
.subscribe(
res => {
console.log(res);
var resp = res.Results[0].results.map(x => {
return {id: x.ID, severity: x.CVSS, cve_link: x.link };
} );
该代码有效,但存在死锁。 我不确定我的代码有什么问题
答案 0 :(得分:2)
我们可以迭代通过通道发送的值。为了打破这种迭代通道,需要明确关闭。否则,范围将永远与无通道相同地被阻塞。在您的代码中,您没有关闭sum
(用于打印功能sumValues
通道)通道。这就是为什么跟踪功能将永远被阻止的原因。
func print(sumValues <-chan string ){
for val := range sumValues {
fmt.Println(val)
}
}
因此,您必须在sum
函数中的所有go例程完成之后关闭doSum
函数中的doSum
通道(否则,在关闭sum
通道之前, go例程已完成)。您可以使用sync.WaitGroup
来做到这一点。请参见下面更新的doSum
函数:
func doSum(sum chan<- string, oddChan <-chan int, evenChan <-chan int) {
var waitGroup sync.WaitGroup
waitGroup.Add(2) // Must wait for 2 calls to 'done' before moving on
go func(sum chan<- string) {
s1 := 0
for val := range oddChan {
s1 += val
}
sum <- fmt.Sprint("sum of odd number = ", s1)
waitGroup.Done()
}(sum)
go func(sum chan<- string) {
s1 := 0
for val := range evenChan {
s1 += val
}
sum <- fmt.Sprint("sum of even number = ", s1)
waitGroup.Done()
}(sum)
// Waiting for all goroutines to exit
waitGroup.Wait()
// all goroutines are complete now close the sum channel
close(sum)
}