Choose by time.

package main

import "time"

func main() {
    chan_never_used := make(chan int, 10)

    c := make(chan int, 10)
    for {
        select {
        case <-time.After(time.Second):
            c <- 0
        case c <- <-chan_never_used:
        }

        println(<-c)
    }
}

      

https://play.golang.org/p/7hZMdITecg

The above code results in fatal error: all goroutines are asleep - deadlock!

.

But if I change one line:

package main

import "time"

func main() {
    chan_never_used := make(chan int, 10)

    c := make(chan int, 10)
    for {
        select {
        case <-time.After(time.Second):
            c <- 0
        case n := <-chan_never_used: // This line changed
            c <- n                   // Add this line
        }

        println(<-c)
    }
}

      

Works well.

Why is the first version of the code deadlocked, and why would this change make the code work?

+3


source to share


1 answer


According to the standard, the select statement contains a bunch of Send or Receive report .

In this case, it is the send statement.

The send operator is defined as:

SendStmt = Channel "<-" Expression .
Channel  = Expression .

      



Looking at your code:

case c <- <-chan_never_used:

      

Faction Channel

c

, faction Expression

<-chan_never_used

.

Thus, the semantics of select

the (potentially) non-blocking send operator does not apply, since it is an expression that blocks. And before applying Send Statement semantics, the Expression part must be fully evaluated.

+2


source







All Articles