Distributed Programming Language Sampler: Go
Table of Contents
1 Facts
2 Hype
3 Hello world
package main import "fmt" func main() { fmt.Println("Hello World!") }
4 Quick Sort
% from http://stackoverflow.com/questions/15802890/ func qsort(a []int) []int { if len(a) < 2 { return a } left, right := 0, len(a) - 1 pivotIndex := rand.Int() % len(a) a[pivotIndex], a[right] = a[right], a[pivotIndex] for i := range a { if a[i] < a[right] { a[i], a[left] = a[left], a[i] left++ } } a[left], a[right] = a[right], a[left] qsort(a[:left]) qsort(a[left + 1:]) return a }
5 Concurrently Say "Enjoy" "Rosetta" "Code": Goroutine
Goroutine is a play on coroutine.
"Simplest and most direct solution: Start three goroutines, give each one a word. Each sleeps, then returns the word on a channel. The main goroutine prints words as they return. The print loop represents a checkpoint–main doesn't exit until all words have returned and been printed."
package main import ( "fmt" "math/rand" "time" ) func main() { words := []string{"Enjoy", "Rosetta", "Code"} rand.Seed(time.Now().UnixNano()) q := make(chan string) for _, w := range words { go func(w string) { time.Sleep(time.Duration(rand.Int63n(1e9))) q <- w }(w) } for i := 0; i < len(words); i++ { fmt.Println(<-q) } }
6 Concurrently Say "Enjoy" "Rosetta" "Code": Afterfunc
time.Afterfunc
combines the sleep and the goroutine
start. log.Println
serializes output in the case goroutines attempt
to print concurrently. sync.WaitGroup
is used directly as a
checkpoint.
package main import ( "log" "math/rand" "os" "sync" "time" ) func main() { words := []string{"Enjoy", "Rosetta", "Code"} rand.Seed(time.Now().UnixNano()) l := log.New(os.Stdout, "", 0) var q sync.WaitGroup q.Add(len(words)) for _, w := range words { w := w time.AfterFunc(time.Duration(rand.Int63n(1e9)), func() { l.Println(w) q.Done() }) } q.Wait() }
7 Concurrently Say "Enjoy" "Rosetta" "Code": Select
This solution might stretch the intent of the task a bit. It is concurrent but not parallel. Also it doesn't sleep and doesn't call the random number generator explicity. It works because the select statement is specified to make a "pseudo-random fair choice" among multiple channel operations. package main
import "fmt"
func main() { w1 := make(chan bool, 1) w2 := make(chan bool, 1) w3 := make(chan bool, 1) for i := 0; i < 3; i++ { w1 <- true w2 <- true w3 <- true fmt.Println() for i := 0; i < 3; i++ { select { case <-w1: fmt.Println("Enjoy") case <-w2: fmt.Println("Rosetta") case <-w3: fmt.Println("Code") } } } }
8 Compute the Digits of Pi
9 Misc
- ./languageSampler.html
- http://www.lunabase.org/~faber/blog/?p=1361 Playing with Go: a concurrent quicksort May 2012
- http://rosettacode.org/wiki/Concurrent_computing#Go