Home  >  Article  >  Backend Development  >  There is a problem with the go channel, sending on a closed channel

There is a problem with the go channel, sending on a closed channel

WBOY
WBOYforward
2024-02-11 18:21:081243browse

go 通道出现问题,在封闭通道上发送

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.

Question content

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:

CB14CE50B218D8EAB916B15CD95527D5

What 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

Solution

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!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete