02 Concurrency - Goroutine and Channel
Concurrency in programming means running multiple tasks simultaneously. In Go, it is realized by Goroutine and Channel.
Goroutine
A goroutine is a lightweight thread of execution. It is mainly used to run a task while allowing other task run at the same time. Look at the example code below.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main
import "fmt"
func main() {
//inline goroutine
go func() { fmt.Println("First goroutine") }()
//call a function as goroutine
go goroutineExampleFunc()
fmt.Println("Print after two goroutines")
}
func goroutineExampleFunc() {
fmt.Println("Second goroutine")
}
If you run the above code, you only see Print after two goroutines
only as an output. That’s because it fires up each goroutines(line 7 and 9 each) and moves down to execute the line 10 without waiting the two goroutines finish. Because the line 10 is executed and the main()
execution is done ahead of both fmt.Println
inside of the two goroutines, both goroutine Println
results are not printed out. To fix this issue, you need to use channel between goroutines.
Channel
Channel makes communication possible between goroutines. It allows you to pass in a certain information from one goroutine to another. The way to use the channel is following:
- Assign a new channel:
ch := make(chan int)
- Send
1
to a channel:ch <- 1
- Store the current value in the channel:
var := <- ch
Let’s take a look at the code below. I declare a new channel called ch
on line 6 and send 1
to the channel inside the first goroutine and 2
inside the second goroutine. And the line 16 will print out what number the channel at the end of main()
execution.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main
import "fmt"
func main() {
ch := make(chan int)
//inline goroutine
go func() {
fmt.Println("First goroutine")
ch <- 1
}()
//call a function as goroutine
go goroutineExampleFunc(ch)
fmt.Println("Print after two goroutines")
i := <-ch
fmt.Println("Recieved ", i)
}
func goroutineExampleFunc(ch chan int) {
fmt.Println("Second goroutine")
ch <- 2
}
Everytime you run the above code, you will find different outputs. Below is my outputs.
The Channel does not change the way goroutines function. It just gives us a better visibility of which goroutine was executed until which line while main()
function is running.
Note: I reference Parikshit Agnihotry’s Understanding the context package in golang to create this post. Please visit his page for more detailed explanation.