Go - Concurrency
Concurrency is part of the language, not a library. 3 key concepts:
- goroutine: lightweight threads.
- channels: typed pipes used to communicate and synchronize between goroutines.
- select: control structure to coordinate concurrent operations.
What is goroutine?
A goroutine is a function or method that executes concurrently alongside any other goroutines using a special goroutine thread. Goroutine threads are more lightweight than standard threads, with most Golang programs using thousands of goroutines at once.
- to create a goroutine, add the
go
keyword before the function declaration.
What are Go channels?
Channels are used to transfer data between goroutines.
- a channel can transfer data of the same type.
- bidirectional.
Receivers always block until there is data to receive.
If the channel is unbuffered, the sender blocks until the receiver has received the value. If the channel has a buffer, the sender blocks only until the value has been copied to the buffer; if the buffer is full, this means waiting until some receiver has retrieved a value.
A buffered channel can be used like a semaphore, for instance to limit throughput.
A channel is created by chan
.
var channel_name chan Type
channel_name:= make(chan Type)
To send and received data:
- send data:
channel_name <- element
- receive data:
element := <-Mychannel
read vs write
chan
// read-write<-chan
// read onlychan<-
// write only
How to stop a gorountine?
To make a goroutine stoppable, let it listen a quit channel.
// Create a quit channel.
quit := make(chan bool)
go func() {
for {
select {
case <-quit:
return
default:
// ...
}
}
}()
// Send `true` to quit channel.
quit <- true
How to handle errors from goroutines?
errs := make(chan error, 1)
go func() {
errs <- foo()
}()
// ...
if err := <-errs; err != nil {
// handle error
}