During the past year and as part of our philosophy of continuous improvement, we have been conducting various shared-training sessions, in which our team members themselves share their knowledge, experiences and ideas. As we know, constant training and continuous learning are essential to keep up to date in a constantly evolving technological world.
In this series of posts, we will discuss some key aspects of these sessions.
Training Pill 01:
Routines and channels in GO
Teach:
Alex Coll
Go is a language:
– Typing: intX and uintX¹, float32/64, byte and rune (aliases of uint8 and int32, used to represent char), boolean, string and complex (similar to float, but for complex numbers).
– Parameter passing by value
– Pointers
• Garbage collector → mark-and-sweep: the objects that can be referenced by the user are marked. After that, the heap is cleared of untagged (unreachable) objects.
Goroutines
We can understand goroutines as execution threads². Let us imagine the case of the following program:
func f(start, end int) {
for i := start; i < end; i++ {
fmt.Println(i) }
}
func main() {
go f(4, 7)
go f(7, 11)
f(1, 4) time.Sleep(time.Second) fmt.Println(“done”)
}
Channels
Channels are the communication mechanism between goroutines. For the above case, let’s imagine that we want to add up the numbers instead of printing them, and send the total to the channel:
var ch = make(chan int, 3)
func f(start, end int) { total := 0
for i := start; i < end; i++ { total += i
}
ch <- total }
func g() {
for n := range ch {
fmt.Println(“Number “, n) }
}
func main() {
defer close(ch)
go f(4, 7)
go f(7, 11)
f(1, 4)
go g() time.Sleep(time.Second) fmt.Println(“done”)
}
The way we use a channel differs depending on the objective we have with it:
– If it is write only, we can indicate ch chan<-
– If it is read only, ch <-chan
– If it is both, ch chan
As for creation
ch := make(chan int) → Unbuffered: blocking until another goroutine receives the value.
ch := make(chan int, 5) → When we know the amount of data we are going to use.
Notes:
1: X can be 8, 16, 32 and 64. Whether int or uint is used is platform dependent.
2: Differences between threads and goroutines are minimal:
– Stack: ~2MB fixed for threads; and 2KB for goroutines (but can grow if needed).
– Scheduling: OS for threads; m:n multiplexing for Go (m goroutines on n threads)
– Identity: unique ID for threads; goroutines do not have