Programmeren in Go/Channels
Uiterlijk
Channels worden gebruikt om te wachten en om informatie uit te wisselen, bijvoorbeeld over de status van een berekening.
var quit = make(chan bool) // Maakt een channel met communicatietype bool func main() { go func() { fmt.Print("hoi") quit <- true // stuur waarde true naar channel quit }() x := <-quit // Wacht op quit en sla waarde op in x, gebruik "<-quit" om niks op te slaan! fmt.Print(x) // Geeft output true in console }
We kunnen dat zo vaak als we willen communiceren met een Goroutine.
var comm = make(chan int) func main() { go func() { i := 0 for { time.Sleep(1000000000) comm <- i // Stuur nummer van berekening door naar channel comm i++ } }() for { x := <-comm fmt.Printf("%d \n", x) } }
We kunnen meerdere Goroutines parallel uitvoeren. Om meerdere channels aan te maken gebruiken we channelnaam := make(chan Type, aantal). De volgende code simuleert een hond met 4 koppen die elk 1 seconde nodig hebben om een brok op te eten.
package main import "fmt" import "time" const Cores = 4 type Hond struct { x,y int ren bool stuks int } func EetBrok(h *Hond, c chan bool) { time.Sleep(1000000000) h.stuks = h.stuks - 1 fmt.Printf("Brok opgegeten, nog %d\n", h.stuks) c<-true } func (h *Hond) EetBrokken(brokken int) { if h.ren { // Als hond niet rent kan hond geen brok eten. return } h.stuks = brokken c := make(chan bool, Cores) j := brokken / Cores for k:=0; k<j; k++ { // We willen (brokken / Cores) keer met 4 koppen eten for i:= 0; i<Cores; i++ { // We vullen 4 channels go EetBrok(h, c) } for i:= 0; i<Cores; i++ { // We wachten op de 4 channels <-c } } nogtedoen := h.stuks // Als aantal brokken niet te delen is door 4 moeten we nog een aantal brokken eten if nogtedoen==0 {return} for i:=0; i<nogtedoen; i++ { go EetBrok(h, c) } for i:= 0; i<nogtedoen; i++ { <-c } } func main(){ rex := &Hond{7, 9, false, 0} rex.EetBrokken(50) }