Advertisement
In this blog, we will learn about Golang Goroutine Syntax and Creation to achieve Concurrency in Golang, which is one of the most important features of Golang.
Let us see what we will be learning in this Golang Goroutine Syntax and Creation blog.
- What are Goroutines and How to create Goroutines in Golang?
- How we can synchronize Goroutines using WaitGroups and Mutexes in Golang?
What are Goroutines in Golang?
Golang Goroutines ( also known as lightweight threads ) are functions or methods that help us to achieve concurrency in our code. These are called lightweight threads because the cost of goroutine creation is less than the creation of threads.
Other languages rely on Operating System for the creation of threads, and the cost of creation and destruction of OS threads is very expensive as it takes almost 1 MB of the stack in the RAM.
Golang has implemented its own type of threads that are called goroutines. The goroutines take very little space in RAM max of 4 KB, and thus the cost of creation and destruction of goroutines or threads in The Go Programming Language is very cheap.
Goroutines create an abstraction of the OS thread (i.e Green Thread). The Go runtime has a scheduler that maps the Goroutines to the OS threads, and the OS threads then assign each process a processing time.
Golang Goroutine Syntax
Syntax:
go
Example:
go display()
The Golang Goroutines have the simplest syntax in the Go Programming Language, any function can be made concurrent just by preceding the function call with go keyword.
This simple change makes a function call concurrent in Golang.
Golang Goroutine Creation
func routine() {
fmt.Println("Golang Goroutine")
}
func main() {
go routine()
}
When this program is run we get no output. This is because the main function itself is a goroutine and when we specify goroutine inside the main function another lightweight thread is created and the function is assigned to that thread. But, till the function is being assigned to that thread, the main function thread’s execution is over and we don’t see any output.
Let’s sleep the main function for a few seconds or milliseconds and then see the output:
Time package is imported for this example.
func routine() {
fmt.Println("Golang Goroutine")
}
func main() {
go routine()
time.Sleep(time.Millisecond * 10)
}
Output:
Golang Goroutine
Now, the output is received, but why?
This happens because we forcefully make our main function sleep for 10 milliseconds and within that time the function is assigned to the goroutine and is executed concurrently and then the main function thread’s execution stops and hence the output is received.
Golang Goroutine Anonymous functions
func main() {
message := "Hello Go routine"
go func() {
fmt.Println(message)
}()
time.Sleep(time.Millisecond * 10)
}
Output:
Hello Go routine
This example might be confusing, as the message variable is in the scope of the main function and the anonymous function is a goroutine and has a different execution stack from the main function, then how this anonymous function is able to access the message variable.
The answer is Golang has a property of Closures (also in JavaScript) which says that the outer scoped variables can be accessed by the inner scoped functions even if they have different execution stacks.
The Closures property of Golang is implemented in Go runtime.
Let’s see another example:
func main() {
message := "Hello Go routine"
go func() {
fmt.Println(message)
}()
message = "Message Changed"
time.Sleep(time.Millisecond * 10)
}
Output:
Message Changed
To understand goroutine in Golang, we will have to understand the main function thread.
The main function goroutine doesn’t stop execution till it encounters the sleep function and thus the message variable is changed and thus the anonymous function goroutine prints the changed message variable.
This creates Race Conditions in the Code.
How can this problem be solved?
One of the solutions is to not use the closure variable rather pass the variable in the anonymous function call.
Example:
func main() {
message := "Hello Go routine"
go func(msg string) {
fmt.Println(msg)
}(message)
message = "Message Changed"
time.Sleep(time.Millisecond * 10)
}
Output:
Hello Go routine
Also, read Why Golang is called the future of Server-side language?
Learn more about Goroutines in Golang from the official Documentation.