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)
}