# Concurrency in Go
Go has built-in concurrency. Concurrency and parallel execution are different things: you need concurrency (program structure) to enable parallel execution; actual parallelism during execution depends on the hardware.
For concurrency, Go offers so-called Goroutines and Channels.
# Goroutines
A Goroutine is a concurrent thread managed by the Go runtime.
To call a goroutine use the following:
If you run this program, you will see that both doSomething(10)
functions work concurrently. You can wait with time.Sleep(10*time.Second)
to see this in action.
# Channels
Go offers channels for communication between goroutines. Channels may be buffered or unbuffered. You can create an unbuffered channel with the following:
You can use this channel to send and receive messages with the <-
operator.
Send to channel ch
as follows:
Read from channel ch
as follows:
Now write an example using channels:
Run this program. What happened?
In this case, you do not need to use time.Sleep
anymore, because sends and receives are blocked until the other side is ready.
To avoid blocking, you can create buffered channels:
When a buffered channel is full, sends to it are blocked. When one is empty, receives from it are blocked.
You can iterate over the values of a channel if it is closed:
Always close the channel (c) before you iterate over it. If you want to wait for multiple communication operations, Go offers select
. This works similar to switch
:
The default case will run if no other channel is ready.
To summarize, this section has explored:
- How Go has built-in concurrency (program structure) which enables parallel execution, which in turn is dependent on the hardware.
- Goroutines, which are concurrent threads managed by the Go runtime.
- Channels, which permit communication between goroutines and can be buffered or unbuffered.
Further readings
Look into Mutexes, which we did not talk about here. This can be important for managing concurrency: