Go Goroutines
Goroutines
A goroutine provides concurrency in Go. Goroutines are lightweight and can run concurrent work efficiently.
The following example starts funcA() as a goroutine with go while the main function continues its own work.
package main
import (
"fmt"
"time"
)
func funcA() {
for i := 0; i < 10; i++ {
fmt.Print("A")
time.Sleep(10 * time.Millisecond)
}
}
func main() {
go funcA()
for i := 0; i < 10; i++ {
fmt.Print("M")
time.Sleep(20 * time.Millisecond)
}
}
Output:
MAAMAAAMAAMAAMAMMMMM
The next example uses a channel to wait for a goroutine to finish. chan declares a channel type, and <- sends or receives a message through a channel.
package main
import (
"fmt"
"time"
)
func funcA(chA chan<- string) {
time.Sleep(3 * time.Second)
chA <- "Finished" // send a message to the channel
}
func main() {
chA := make(chan string) // create a channel
defer close(chA) // close it after use
go funcA(chA) // start the goroutine
msg := <-chA // receive a message from the channel
fmt.Println(msg)
}
Output:
Finished
The following example uses select to wait for both funcA() and funcB().
package main
import (
"fmt"
"time"
)
func funcA(chA chan<- string) {
time.Sleep(1 * time.Second)
chA <- "funcA Finished"
}
func funcB(chB chan<- string) {
time.Sleep(2 * time.Second)
chB <- "funcB Finished"
}
func main() {
chA := make(chan string)
chB := make(chan string)
defer close(chA)
defer close(chB)
finflagA := false
finflagB := false
go funcA(chA)
go funcB(chB)
for {
select {
case msg := <-chA:
finflagA = true
fmt.Println(msg)
case msg := <-chB:
finflagB = true
fmt.Println(msg)
}
if finflagA && finflagB {
break
}
}
}
Output:
funcA Finished
funcB Finished