How to Write a New Git Protocol
rovaughn.github.io162 pointsby alecrn13 comments
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
fmt.Println(runtime.NumCPU(), runtime.GOMAXPROCS(0))
started := make(chan bool)
go func() {
started <- true
for {
atomic.AddUint64(&a, uint64(1))
}
}()
<-started
for {
fmt.Println(atomic.LoadUint64(&a))
time.Sleep(time.Second)
}
}
Here we explicitly wait until the goroutine is started, so we know it's scheduled by the time our other loop runs. Here on my computer with go1.8 linux/amd64 it still optimizes out the while loop, which makes sense as nothing changed that would convince the optimizer the loop should remain given the compiler's current logic.
Go's concurrency model is inspired by Hoare's communicating sequential processes which kinda has the same idea: http://usingcsp.com/cspbook.pdf
For instance in this program:
An unbuffered channel read is always matched with a corresponding write. Let's call the point at which `point1 <- true` occurs and `<-point1` occurs T1 and the point at which `point2 <- true` occurs and `<-point2` occurs T2. fmt.Println("hello") and time.Sleep(3*time.Second) are both guaranteed to occur between T1 and T2. If we didn't have T2 there's no guarantee fmt.Println("hello") would run before the program exits.
Maybe I'm wrong but this is my understanding of Hoare's and go's concurrency model.