我遇到了这些错误
致命错误:所有 goroutine 都在休眠 - 死锁!
`goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc0000081e0?)
C:/Program Files/Go/src/runtime/sema.go:71 +0x25
sync.(*WaitGroup).Wait(0x0?)
C:/Program Files/Go/src/sync/waitgroup.go:118 +0x48
main.main()`
但是我使用同步Wait()等工具。怎么了?我的代码:
package main
import (
"fmt"
"sync"
)
func sender(id int, data []int, out chan<- [2]int, wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < len(data); i += 2 {
out <- [2]int{data[i], data[i+1]}
}
}
func service(in <-chan [2]int, c, d int, out chan<- int, wg *sync.WaitGroup) {
defer wg.Done()
for pair := range in {
sum := pair[0] + pair[1]
if sum >= c && sum <= d {
out <- sum
}
}
}
func receiver(in <-chan int, wg *sync.WaitGroup) {
defer wg.Done()
line := 1
for sum := range in {
fmt.Printf("Line %d: Received sum %d\n", line, sum)
line++
}
}
func main() {
data1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
data2 := []int{11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
data3 := []int{21, 22, 23, 24, 25, 26, 27, 28, 29, 30}
data4 := []int{31, 32, 33, 34, 35, 36, 37, 38, 39, 40}
c, d := 15, 50
senderToService := make(chan [2]int, 10)
serviceToReceiver := make(chan int, 10)
var wg sync.WaitGroup
// Start sender goroutines
wg.Add(4)
go sender(1, data1, senderToService, &wg)
go sender(2, data2, senderToService, &wg)
go sender(3, data3, senderToService, &wg)
go sender(4, data4, senderToService, &wg)
// Close senderToService channel once all senders are done
go func() {
wg.Wait()
close(senderToService)
}()
// Start service goroutine
wg.Add(1)
go service(senderToService, c, d, serviceToReceiver, &wg)
// Close serviceToReceiver channel once the service is done
go func() {
wg.Wait()
close(serviceToReceiver)
}()
// Start receiver goroutine
wg.Add(1)
go receiver(serviceToReceiver, &wg)
// Wait for all goroutines to finish
wg.Wait()
}
我使用单个 WaitGroup (wg) 来管理管道的三个独立阶段之间的同步: 发送阶段产生数据。 服务阶段处理数据。 接收器阶段消耗处理后的数据。 当我在主函数中调用 wg.Wait() 时,它会等待所有阶段的所有减量。通道 senderToService 和 serviceToReceiver 在等待 wg.Wait() 的匿名 goroutine 中关闭。那么根本原因在哪里以及如何解决它?
问题在于应用程序使用单个等待组来等待三个不同的事件(发送者完成、服务完成、接收者完成)。 一种解决方法是将程序更改为三个等待组。 一个更简单的解决方法是消除不必要的等待组的使用。
func sender(id int, data []int, out chan<- [2]int, wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < len(data); i += 2 {
out <- [2]int{data[i], data[i+1]}
}
}
func service(in <-chan [2]int, c, d int, out chan<- int) {
defer close(out)
for pair := range in {
sum := pair[0] + pair[1]
if sum >= c && sum <= d {
out <- sum
}
}
}
func receiver(in <-chan int) {
line := 1
for sum := range in {
fmt.Printf("Line %d: Received sum %d\n", line, sum)
line++
}
}
func main() {
data1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
data2 := []int{11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
data3 := []int{21, 22, 23, 24, 25, 26, 27, 28, 29, 30}
data4 := []int{31, 32, 33, 34, 35, 36, 37, 38, 39, 40}
c, d := 15, 50
senderToService := make(chan [2]int, 10)
serviceToReceiver := make(chan int, 10)
var wg sync.WaitGroup
// Start sender goroutines
wg.Add(4)
go sender(1, data1, senderToService, &wg)
go sender(2, data2, senderToService, &wg)
go sender(3, data3, senderToService, &wg)
go sender(4, data4, senderToService, &wg)
go func() {
wg.Wait()
close(senderToService)
}()
go service(senderToService, c, d, serviceToReceiver)
receiver(serviceToReceiver)
}