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

WBOY
Release: 2024-02-11 18:21:08
forward
1213 people have browsed it

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
Copy after login

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")
    }
}
Copy after login

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!

Related labels:
source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!