Syntax
A goroutine is a lightweight thread managed by the Go runtime.
go f(x, y, z) // notice go keyword
starts a new goroutine running:
f(x, y, z)
The evaluation of f, x, y, and z happens in the current goroutine and the execution of f happens in the new goroutine.
All goroutines in a single program share the same address space. So access to shared memory must be synchronized. The sync package provides useful primitives, although you won’t need them much in Go as there are other primitives.
Example - Goroutine without delay
The following program will print “Hello from main goroutine” all the time.
func printGreetings(source string) {
for i := 0; i < 9; i++ {
fmt.Println("नमस्ते किंशुक!", i, source)
}
}
func main() {
go printGreetings("From Goroutine")
printGreetings("From Main Function")
}
Output:
नमस्ते किंशुक! 0 From Main Goroutine
नमस्ते किंशुक! 1 From Main Goroutine
नमस्ते किंशुक! 2 From Main Goroutine
नमस्ते किंशुक! 3 From Main Goroutine
नमस्ते किंशुक! 4 From Main Goroutine
नमस्ते किंशुक! 5 From Main Goroutine
नमस्ते किंशुक! 6 From Main Goroutine
नमस्ते किंशुक! 7 From Main Goroutine
नमस्ते किंशुक! 8 From Main Goroutine
Program is terminated when main() function execution is completed. When the program terminates, all Goroutines are terminated regardless of the fact if all the Goroutines has completed execution or not.
Example - Adding delay
The next program will, most likely, print both “Hello from main goroutine” and “Hello from another goroutine”. They may be printed in any order. Yet another possibility is that the second goroutine is extremely slow and doesn’t print its message before the program ends.
func printGreetings(source string) {
for i := 0; i < 9; i++ {
fmt.Println("नमस्ते किंशुक!", i, source)
}
time.Sleep(time.Millisecond * 1) // Sleep for 1 millisecond
}
func main() {
go printGreetings("From Another Goroutine")
printGreetings("From Main Goroutine")
}
We can also add the delay in main function:
func printGreetings(source string) {
for i := 0; i < 9; i++ {
fmt.Println("नमस्ते किंशुक!", i, source)
}
// time.Sleep(time.Millisecond * 1) // Sleep for 1 millisecond
}
func main() {
go printGreetings("From Another Goroutine")
printGreetings("From Main Goroutine")
time.Sleep(time.Millisecond *1000)
}
Output:
नमस्ते किंशुक! 0 From Main Goroutine
नमस्ते किंशुक! 1 From Main Goroutine
नमस्ते किंशुक! 2 From Main Goroutine
नमस्ते किंशुक! 3 From Main Goroutine
नमस्ते किंशुक! 4 From Main Goroutine
नमस्ते किंशुक! 5 From Main Goroutine
नमस्ते किंशुक! 6 From Main Goroutine
नमस्ते किंशुक! 7 From Main Goroutine
नमस्ते किंशुक! 8 From Main Goroutine
नमस्ते किंशुक! 0 From Another Goroutine
नमस्ते किंशुक! 1 From Another Goroutine
नमस्ते किंशुक! 2 From Another Goroutine
नमस्ते किंशुक! 3 From Another Goroutine
नमस्ते किंशुक! 4 From Another Goroutine
नमस्ते किंशुक! 5 From Another Goroutine
नमस्ते किंशुक! 6 From Another Goroutine
नमस्ते किंशुक! 7 From Another Goroutine
नमस्ते किंशुक! 8 From Another Goroutine
Goroutines with anonymous function
// Executing anonymous function as Goroutine
go func() {
//
}() // Note the parentheses. We must call the anonymous function
Example - More realistic example
Here is a somewhat more realistic example, where we define a function that uses concurrency to postpone an event.
// Publish prints text to stdout after the given time
// It doesn’t block but returns right away.
func Publish(text string, delay time.Duration) {
go func() {
time.Sleep(delay)
fmt.Println("Goroutine Update:", text)
}() // Note the parentheses. We must call the anonymous function.
}
This is how you might use the Publish function.
func main() {
Publish("A new goroutine has started.", 3*time.Second)
fmt.Println("Let’s hope that another Goroutine will publish before main finishes.")
// Wait for the text to be published.
time.Sleep(5 * time.Second)
fmt.Println("Main Goroutine Update: 5 seconds later, calling it done.")
}
The program will, most likely, print the following three lines, in the given order and with a 3 second break in between each line.
Output:
Let’s hope that another Goroutine will publish before main finishes.
Goroutine Update: A new goroutine has started.
Main Goroutine Update: 5 seconds later, calling it done.
In general it’s not possible to arrange for threads to wait for each other by sleeping. Go’s main method for synchronization is to use channels.
Implementation
Goroutines are lightweight, costing little more than the allocation of stack space. The stacks start small and grow by allocating and freeing heap storage as required. Internally goroutines act like coroutines that are multiplexed among multiple operating system threads.
Advantages of Goroutines over Threads
Goroutineshave a faster startup time thanthreads.Goroutinescome withbuilt-in primitivesto communicate safely between themselves called aschannels.Goroutinesare extremely cheap when compared tothreads. They are only a fewkbinstack sizeand thestackcan grow and shrink according to needs of the application whereas in the case ofthreadsthestack sizehas to be specified and isfixed.
References http://www.golangbootcamp.com/book/concurrency