[ Go] GoRoutines and Channels
A goroutine is the Go way of suing threads, we open a goroutine just by invoking any function with a go
prefix.
go functionCall()
Goroutines can communicate through channels, an special type of variable, a channel contains a value of any kind, a routine can define a value for a channel and other routine can wait for that value.
Channels can be buffered or not.
// define a chan type is string
var foo chan string
// constructor make
bar := make(chan string)
// write into channel
bar <- "hello"
// other can read message
message := <- bar
Goroutines example:
// Without go routines
package main
import (
"fmt"
"time"
)
func printMessage(text string) {
for i := 0; i < 3; i++ {
fmt.Println(text)
time.Sleep(300 * time.Millisecond)
}
}
func main() {
printMessage("Go is great!")
printMessage("Rust is great!")
}
Output:
/*
Go is great!
Go is great!
Go is great!
Rust is great!
Rust is great!
Rust is great!
/*
Without Goroutines
func main() {
go printMessage("Go is great!")
printMessage("Rust is great!")
}
Output:
/*
Rust is great!
Go is great!
Go is great!
Rust is great!
Rust is great!
Go is great!
/*
Notice that you cannot do
func main() {
go printMessage("Go is great!")
go printMessage("Rust is great!")
}
No output for this code, because the main goroutines ends when main function exit, which also ends sub goroutines.
Channel
package main
import (
"fmt"
"time"
)
func printMessage(text string, chanMsg chan string) {
for i := 0; i < 3; i++ {
fmt.Println(text)
time.Sleep(300 * time.Millisecond)
}
chanMsg <- "Done!"
}
func main() {
chanMsg := make(chan string)
go printMessage("Go is great!", chanMsg)
// Wait channel message then print
response := <-chanMsg
fmt.Println(response)
}
/*
Go is great!
Go is great!
Go is great!
DONE!
*/
It is also possible to use buffer, for example we want to buffer size 2:
func printMessage(text string, chanMsg chan string) {
for i := 0; i < 3; i++ {
fmt.Println(text)
time.Sleep(300 * time.Millisecond)
}
chanMsg <- "Done!"
chanMsg <- "Done!2"
// chanMsg <- "Done!"
}
func main() {
chanMsg := make(chan string, 2)
go printMessage("Go is great!", chanMsg)
// Wait channel message then print
response := <-chanMsg
response2 := <-chanMsg
fmt.Println(response)
fmt.Println(response2)
}
/*
Go is great!
Go is great!
Go is great!
Done!
Done!2
*/
To avoid deadlocks you have to close the channels before ending the program with close(chan)