Break inside of for-select

9,087 views
Skip to first unread message

James Aguilar

unread,
Nov 14, 2009, 3:52:05 PM11/14/09
to golang-nuts
I have a program that's using the quit channel idiom to notice when
its child channels have stopped producing output. Actually, it's just
an attempt to make the sieve example in the go tutorial quit cleanly
rather than printing a message about deadlock. Sadly the quit channels
make it a little more complicated.

Anyway, I was doing something like this:

in, inQuit := foo();
for {
select {
case i := <-in:
// Do something.
case <-inQuit:
break;
}
}

And I would still get the deadlock messages. When I changed break to
return, it started finishing correctly.

I'm guessing that break inside select applies to the select, not to
the for loop that encloses it. I have a few questions about this:

1. What's the purpose of applying the break to the select, since
execution doesn't fall through the cases as in a traditional C/C++
switch statement? I would have expected break here to behave more like
breaks in an if-block, where they apply to the outer loop, not to the
if-context itself.

2. Since break does apply to select, what's the idiomatic way to break
out of a for-select loop? I would guess something like

for s := false; !s; {
select {
case i := <-in:
// Do something
case s = <-inQuit:
break;
}
}

3. On a tangential note, what's the ordinary way to name the channels
when you have a function that has an input quit channel and an output
quit channel? inQuit and outQuit seem fine, but if there's a
"standard" way to name them it would be nice to know.

-- James

Russ Cox

unread,
Nov 14, 2009, 4:17:44 PM11/14/09
to James Aguilar, golang-nuts
> 1. What's the purpose of applying the break to the select, since
> execution doesn't fall through the cases as in a traditional C/C++
> switch statement? I would have expected break here to behave more like
> breaks in an if-block, where they apply to the outer loop, not to the
> if-context itself.

There's an implicit break at the end of the block but it's still
useful sometimes to break out early.

> 2. Since break does apply to select, what's the idiomatic way to break
> out of a for-select loop? I would guess something like

See http://golang.org/doc/go_spec.html#Break_statements

> 3. On a tangential note, what's the ordinary way to name the channels
> when you have a function that has an input quit channel and an output
> quit channel? inQuit and outQuit seem fine, but if there's a
> "standard" way to name them it would be nice to know.

Seems fine. If they are connected to different
kinds of servers you might use that to distinguish
them instead of just in and out.

Russ

Anh Hai Trinh

unread,
Nov 15, 2009, 12:39:40 AM11/15/09
to James Aguilar, golang-nuts
> Actually, it's just
an attempt to make the sieve example in the go tutorial quit cleanly
rather than printing a message about deadlock.

If you JUST want to do that, here's a extra snippet to take an arg and
just print out the primes <= n.

import (
"flag";
"strconv";
)

func main() {
flag.Parse();
n, err := strconv.Atoi(flag.Arg(0));
if err != nil {
fmt.Fprintln(os.Stderr, "bad argument")
}
primes := sieve();
for {
p := <-primes;
if p <= n {
fmt.Println(p)
} else {
return
}
}
}

James Aguilar

unread,
Nov 16, 2009, 1:26:23 PM11/16/09
to Anh Hai Trinh, golang-nuts
I was interested in stopping exactly when I had reached the limit number, not on the next prime. :) Of course, since I was just playing with an example, the practical solution is not as interesting as the "right" thing. So, the success condition is processes no more than necessary && no deadlock.
Reply all
Reply to author
Forward
0 new messages