Home > Article > Backend Development > There is a problem with the go channel, sending on a closed channel
php Xiaobian Youzi may encounter some problems during development using the Go language. One of them is a problem when sending data on a closed channel. This problem may cause channel blocking and program stagnation, affecting the operation of the entire application. Before solving this problem, we first need to understand what a closed channel is and why sending data on a closed channel is problematic. Next, we will delve into this issue and provide solutions to fix and optimize our Go applications.
I get a fatal error: "Sending on a closed channel" and sometimes I run this code, I tried multiple solutions but none of them worked, this Is a representation of code that is easy to understand and easy to use for testing:
CB14CE50B218D8EAB916B15CD95527D5What I want is to start the request function n times and get the first completed request, then close the channel and don't send more requests to the channel, if none of the requests complete successfully, wait for all goroutines to complete.
I guess this happens because two or more goroutines check if the channel is closed at the same time, and both try to write in the channel, which results in a fatal error.
mistake:
goroutine 19 [running]: main.request(0xc00000a028, 0xc00000a030, 0x0?) C:/test/main.go:49 +0x135 created by main.main C:/test/main.go:17 +0xd3 panic: send on closed channel
Can anyone explain why this happens?
Thanks in advance
The problem is that the receiving goroutine (main
) closes prematurely outputCh
. Some other goroutine can still try to send on it.
Here is another way:
package main import ( "fmt" "math/rand" "sync" "time" ) func main() { var wg sync.WaitGroup output := make(chan string) stop := make(chan bool) done := make(chan bool) for i := 0; i < 20; i++ { wg.Add(1) go request(output, stop, &wg) } go func() { wg.Wait() done <- true }() firstOutput := <-output fmt.Println("output:", firstOutput) fmt.Println("closing the stop channel") close(stop) <-done fmt.Println("end of main") } func request(output chan string, stop chan bool, wg *sync.WaitGroup) { defer wg.Done() fmt.Println("request started") time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond) select { case output <- "test": fmt.Println("output sent") case <-stop: fmt.Println("stop channel is closed") } }
The above is the detailed content of There is a problem with the go channel, sending on a closed channel. For more information, please follow other related articles on the PHP Chinese website!