How to check a channel is closed or not without reading it?

前端 未结 8 840
别跟我提以往
别跟我提以往 2020-12-12 14:56

This is a good example of workers & controller mode in Go written by @Jimt, in answer to \"Is there some elegant way to pause & resume any other goroutine in golang?

相关标签:
8条回答
  • 2020-12-12 15:34

    From the documentation:

    A channel may be closed with the built-in function close. The multi-valued assignment form of the receive operator reports whether a received value was sent before the channel was closed.

    https://golang.org/ref/spec#Receive_operator

    Example by Golang in Action shows this case:

    // This sample program demonstrates how to use an unbuffered
    // channel to simulate a game of tennis between two goroutines.
    package main
    
    import (
        "fmt"
        "math/rand"
        "sync"
        "time"
    )
    
    // wg is used to wait for the program to finish.
    var wg sync.WaitGroup
    
    func init() {
        rand.Seed(time.Now().UnixNano())
    }
    
    // main is the entry point for all Go programs.
    func main() {
        // Create an unbuffered channel.
        court := make(chan int)
        // Add a count of two, one for each goroutine.
        wg.Add(2)
        // Launch two players.
        go player("Nadal", court)
        go player("Djokovic", court)
        // Start the set.
        court <- 1
        // Wait for the game to finish.
        wg.Wait()
    }
    
    // player simulates a person playing the game of tennis.
    func player(name string, court chan int) {
        // Schedule the call to Done to tell main we are done.
        defer wg.Done()
        for {
            // Wait for the ball to be hit back to us.
            ball, ok := <-court
            fmt.Printf("ok %t\n", ok)
            if !ok {
                // If the channel was closed we won.
                fmt.Printf("Player %s Won\n", name)
                return
            }
            // Pick a random number and see if we miss the ball.
            n := rand.Intn(100)
            if n%13 == 0 {
                fmt.Printf("Player %s Missed\n", name)
                // Close the channel to signal we lost.
                close(court)
                return
            }
    
            // Display and then increment the hit count by one.
            fmt.Printf("Player %s Hit %d\n", name, ball)
            ball++
            // Hit the ball back to the opposing player.
            court <- ball
        }
    }
    
    0 讨论(0)
  • 2020-12-12 15:36

    If you listen this channel you always can findout that channel was closed.

    case state, opened := <-ws:
        if !opened {
             // channel was closed 
             // return or made some final work
        }
        switch state {
            case Stopped:
    

    But remember, you can not close one channel two times. This will raise panic.

    0 讨论(0)
提交回复
热议问题