Go is a concurrent language and not a parallel one. Before discussing how concurrency is taken care in Go, we must first understand what is concurrency and how it is different from parallelism.
What is concurrency?
Concurrency is the capability to deal with lots of things at once. It's best explained with an example.
Let's consider a person jogging. During his morning jog, let's say his shoelaces become untied. Now the person stops running, ties his shoelaces and then starts running again. This is a classic example of concurrency. The person is capable of handling both running and tying shoelaces, that is the person is able to deal with lots of things at once :)
Concurrency and Parallelism - A technical point of view
Large programs are divided into smaller sub-programs. Programs which run their smaller components at the same time is known as concurrency.
Goroutines
A goroutine is a lightweight execution thread in the Go programming language and a function that executes concurrently with the rest of the program.
Goroutines are incredibly cheap when compared to traditional threads as the overhead of creating a goroutine is very low. Therefore, they are widely used in Go for concurrent programming.
To invoke a function as a goroutine, use the go keyword.
Syntax
go foo()
We write go before the function foo to invoke it as a goroutine. The function foo() will run concurrently or asynchronously with the calling function.
example:
package main
import (
"fmt"
"time"
)
// Prints numbers from 1-3 along with the passed string
func foo(s string) {
for i := 1; i <= 3; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s, ": ", i)
}
}
func main() {
// Starting two goroutines
go foo("1st goroutine")
go foo("2nd goroutine")
// Wait for goroutines to finish before main goroutine ends
time.Sleep(time.Second)
fmt.Println("Main goroutine finished")
}
example:
package main
import (
"fmt"
"strconv"
)
func main() {
ch := make(chan string)
for i := 0; i < 10; i++ {
go func(i int) {
for j := 0; j < 10; j++ {
ch <- "Goroutine : " + strconv.Itoa(i)
}
}(i)
}
for k := 1; k <= 100; k++ {
fmt.Println(k, <-ch)
}
}
https://replit.com/@neerajkumar1997/Goroutines?v=1
Send and Receive values from Channel
The main function has two functions generator and receiver. We create a c int channel and return it from the generator function. The for loop running inside anonymous goroutines writing the values to the channel c.
package main
import (
"fmt"
)
func main() {
c := generator()
receiver(c)
}
func receiver(c <-chan int) {
for v := range c {
fmt.Println(v)
}
}
func generator() <-chan int {
c := make(chan int)
go func() {
for i := 0; i < 10; i++ {
c <- i
}
close(c)
}()
return c
}
https://replit.com/@neerajkumar1997/Send-and-Receive-values-from-Channel?v=1
Starting multiple Goroutine
package main
import (
"fmt"
"time"
)
func numbers() {
for i := 1; i <= 5; i++ {
time.Sleep(250 * time.Millisecond)
fmt.Printf("%d ", i)
}
}
func alphabets() {
for i := 'a'; i <= 'e'; i++ {
time.Sleep(400 * time.Millisecond)
fmt.Printf("%c ", i)
}
}
func main() {
go numbers()
go alphabets()
time.Sleep(3000 * time.Millisecond)
fmt.Println("main terminated")
}
https://replit.com/@neerajkumar1997/Starting-multiple-Goroutines?v=1
That's it for Goroutines. Have a good day.
Top comments (0)