When i try to write a program that can calculate the sum of every digit of an int64, i use goroutines to acheive that.However,i get a "send on closed channel" panic .Why?
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
var wg sync.WaitGroup
func setRand(jobchan chan int64) {
rand.Seed(time.Now().Unix())
defer wg.Done()
for i := 0; i < 100; i {
jobchan <- rand.Int63()//when i=2 ,it panic,but the channel isn't closed
}
close(jobchan)
}
func calculateSum(jobchan, resultchan chan int64) {
sum := int64(0)
for i := range jobchan {
sum = 0
for i != 0 {
sum = i % 10
i /= 10
}
resultchan <- sum
}
wg.Done()
}
func main() {
jobChan := make(chan int64, 100)
resultChan := make(chan int64, 100)
wg.Add(1)
go setRand(jobChan)
for i := 0; i < 24; i {
wg.Add(1)
go calculateSum(jobChan, resultChan)
}
close(resultChan)
for i := range resultChan {
fmt.Println(i)
}
wg.Wait()
}
And it quite strange that this only happens when i debug
the program,it runs well when go bulid
the program.
CodePudding user response:
calculateSum
is being run in multiple goroutines. There is nothing to prevent one of the calculateSum
instances to write to resultChan
after it it closed. You have to make sure the channel is closed after all calculateSum
s are done. That means, you have to close the channel after wg.Wait()
.
One way to do it is with another goroutine:
for i := 0; i < 24; i {
wg.Add(1)
go calculateSum(jobChan, resultChan)
}
go func() {
wg.Wait()
close(resultChan)
}()
for i := range resultChan {
fmt.Println(i)
}