why write channel in select block will never failed to default branch.

248 views
Skip to first unread message

zylth...@gmail.com

unread,
Feb 27, 2015, 10:55:46 AM2/27/15
to golan...@googlegroups.com
Hi, groups

I have a question here:

package main
import "fmt"

func main() {
    ch := make(chan int, 1)
    if (1 < 2) {
        fmt.Println("--------");
    }   

    for j := 0; j < 100; j += 1  {
        select {
            case ch <- 0:
                fmt.Println("write 0");
            case ch <- 1:
                fmt.Println("write 1");
            default:
                fmt.Println("fuck0000000000000000000000000000");
        }   
        i := <- ch
        fmt.Println("i = ", i); 
    }   
}

I can get write 0, write 1, while never fuck0000000000000000000000000000
why?

then I add another line:
            case ch <- 2:
                fmt.Println("write 2");
this time I got all write 0, write 1,  write 2;
so it is not a timing problem.

Ian Davis

unread,
Feb 27, 2015, 11:00:29 AM2/27/15
to golan...@googlegroups.com
It looks to me like you have a bufffered channel with size 1. Each iteration of the loop sends to the channel and then immediately reads it off so the channel is empty. Therefore the select can always send to the channel so the default clause will never be used.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
 

Chris Kastorff

unread,
Feb 27, 2015, 11:00:56 AM2/27/15
to golan...@googlegroups.com
From the spec, section "Select Statements":

If one or more of the communications can proceed, a single one that can
proceed is chosen via a uniform pseudo-random selection. Otherwise, if
there is a default case, that case is chosen. If there is no default
case, the "select" statement blocks until at least one of the
communications can proceed.

In your case, the channel is always writable because you pull the data
out of the channel buffer after writing to it. Therefore, the default
case will never run.
> --
> You received this message because you are subscribed to the Google
> Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to golang-nuts...@googlegroups.com
> <mailto:golang-nuts...@googlegroups.com>.

Jason Woods

unread,
Feb 27, 2015, 11:01:49 AM2/27/15
to golang-nuts


On 27 Feb 2015, at 08:10, zylth...@gmail.com wrote:

Hi, groups

I have a question here:

package main
import "fmt"

func main() {
    ch := make(chan int, 1)
    if (1 < 2) {
        fmt.Println("--------");
    }   

    for j := 0; j < 100; j += 1  {
        select {
            case ch <- 0:
                fmt.Println("write 0");
            case ch <- 1:
                fmt.Println("write 1");
            default:
                fmt.Println("fuck0000000000000000000000000000");
        }   
        i := <- ch
        fmt.Println("i = ", i); 
    }   
}

I can get write 0, write 1, while never fuck0000000000000000000000000000
why?

The ch always has room for one entry when it hits select, so when writing it need never block.
Thus it will never hit the default: one of the cases will always succeed without blocking.
It only hits default if all cases would block.

Jason

(Sorry for resend- missed go nuts)
Reply all
Reply to author
Forward
0 new messages