Home > Blockchain >  Why does Go panic : send on closed channel?
Why does Go panic : send on closed channel?

Time:07-08

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 bulidthe 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 calculateSums 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)
}
  •  Tags:  
  • go
  • Related