### Goroutines
A goroutine is a lightweight thread managed by Go runtime.
func say(s string){ for i := 0; i < 5; i++ { time.Sleep(100 * time.Millisecond) fmt.Println(s) } } func main(){ go say("world") say("hello") }
### Channels
Channels are a typed conduit through which you can send and receive values with the channel operator
func sum(s []int, c chan int){ sum := 0 for _, v := range s { sum += v } c <- sum } func main(){ s := []int{7, 2, 8, -9, 4, 0} c := make(chan int) go sum(s[:len(s)/2], c) go sum(s[len(s)/2:], c) x, y := <-c, <-c fmt.Println(x, y, x+y) }
Buffered Channels
func main(){ ch := make(chan int, 2) ch <- 1 ch <- 2 fmt.Println(<-ch) fmt.Println(<-ch) }
– Range and close
A sender can close a channel to indicate that no more values will sent. Receivers can test whether a channel has been closed by assigning a second parameter to the receive expression: after
func fibonacci(n int, c chan int){ x, y := 0, 1 for i := 0; i < n; i++ { c <- x x, y = y, x+y } close(c) } func main(){ c := make(chan int, 10) go fibonacci(cap(c), c) for i := range c{ fmt.Println(i) } }
### Select
The select statement lets a goroutine wait on multiple communication operations.
func fibonacci(c, quit chan int){ x, y := 0, 1 for { select { case c <- x: x, y = y, x+y case <-quit: fmt.Println("quit") return } } } func main(){ c := make(chan int) quit := make(chan int) go func(){ for i := 0; i < 10; i++ { fmt.Println(<-c) } quit <- 0 }() fibonacci(c, quit) }
Default Selection
func main(){ tick := time.Tick(100 * time.Millisecond) boom := time.After(500 * time.Millisecond) for { select { case <-tick: fmt.Println("tick.") case <-boom: fmt.Println("BOOM!") return default: fmt.Println(" .") time.Sleep(50 * time.Millisecond) } } }
– sync.Mutex
type SafeCounter struct { mu sync.Mutex v map[string]int } func (c *SafeCounter) Inc(key string){ c.mu.Lock() c.v[key]++ c.mu.Unlock() } func(c *SafeCounter) Value(key string) int { c.mu.Lock() defer c.mu.Unlock() return c.v[key] } func main(){ c := SafeCounter{v: make(map[string]int)} for i := 0; i < 1000; i++ { go c.Inc("somekey") } time.Sleep(time.Second) fmt.Println(c.Value("somekey")) }
それではEchoでもやりますか