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