Last active
January 26, 2017 03:27
-
-
Save bradclawsie/a344b471d6f3d023aa9f200516407cbd to your computer and use it in GitHub Desktop.
curious correct Go program
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"time" | |
) | |
func main() { | |
c := make(chan struct{},1) | |
go func() { | |
time.Sleep(100 * time.Millisecond) | |
fmt.Printf("0 ") | |
c <- struct{}{} | |
fmt.Printf("1 ") | |
c <- struct{}{} | |
fmt.Printf("2 ") | |
c <- struct{}{} | |
fmt.Printf("3 ") | |
return | |
}() | |
<- c | |
fmt.Printf("done ") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This program runs and exist properly although our intuition might say it will fail.
The program doesn't deadlock and it prints "done" even though it appears to be wrong at first glance.
The chan is of length 1, how is it we can put more than one
struct{}{}
into it? We can't and we don't. The goroutine is launched while the outer scope blocks on polling the chan. The goroutine enqueues astruct{}{}
, and the outer scope dequeues it. While that is happening, the goroutine now can (and typically does) enqueue anotherstruct{}{}
before the final "done" message is printed. At this point, our goroutine should be "stuck" waiting to enqueue a newstruct{}{}
, but it doesn't matter, the program exits and the goroutine itself is stopped.This shows the need for proper synchronization without cleverness.