Do go-routines end when the calling function returns?

Nator Verinumbe
3 min readMar 1, 2021

--

Go-Routines

image source: https://morganwu277.github.io/2018/03/02/Golang-Summary/

Go routines are a way to run functions concurrently in the Go programming language. They are a lightweight alternative to threads, and are used to achieve concurrence in Go programs.

One of the key features of go routines is that they are independent of the calling function, and will continue to execute even after the calling function has returned. This means that go routines will not automatically end just because the calling function has finished executing.

Instead, go routines are managed by the Go runtime, which will schedule them to be run on available CPU cores as needed. Go routines are terminated when they return, or when the program itself exits.

relationship between threads and go-routines

It is important to note that go routines are not meant to replace traditional threads, and are not suitable for every situation. They are designed to be lightweight and efficient, and are best suited for tasks that can be broken down into smaller, independent units of work.

If you need to perform tasks that require more heavyweight synchronization or shared memory, you may be better off using traditional threads or other synchronization mechanisms.

Overall, go routines are a useful tool for achieving concurrence in Go programs, but it is important to understand their limitations and use them appropriately.

So now that we’ve had a clear understanding of how go-routines work, let’s have a look at the code below

package main

import (
"fmt"
"time"
)

func main() {

defer println("Main Function Returned Here")

CallingFunction()

time.Sleep(5 * time.Second) //wait to see
}

func CallingFunction() {
defer println("Calling Function Returned Here")

dataCh := make(chan struct{})

// Start a goroutine that runs an infinite loop that prints a message and sleeps for 1 second in each iteration
go func(ch chan struct{}) {
for i := 0; ; i++ {
fmt.Println("goroutine running: ", i)
if i == 3 {
ch <- struct{}{}
}
time.Sleep(1 * time.Second)
}
}(dataCh)

// Wait for a value to be received on the dataCh channel
<-dataCh

return

}

Output :

goroutine running:  0
goroutine running: 1
goroutine running: 2
goroutine running: 3
Calling Function Returned Here
goroutine running: 4
goroutine running: 5
goroutine running: 6
goroutine running: 7
Main Function Returned Here

Program exited.

Explanation

The calling function starts a goroutine that prints numbers to the console and waits for the goroutine to reach 3 before returning. The go-routine continues running in the background.

func CallingFunction() {

defer println("Calling Function Returned Here")

dataCh := make(chan struct{})

// Start a goroutine that runs an infinite loop that prints a message and sleeps for 1 second in each iteration
go func(ch chan struct{}) {
for i := 0; ; i++ {
fmt.Println("goroutine running: ", i)
if i == 3 {
ch <- struct{}{}
}
time.Sleep(1 * time.Second)
}
}(dataCh)

// Wait for a value to be received on the dataCh channel
<-dataCh

return

}

Conclusion

Question: Do go-routines end when the calling function returns?
Answer: No

If a function that starts a go-routine returns before the goroutine finishes, the goroutine will continue running. The output in this case demonstrates that the calling function returned while the goroutine continued running.

goroutine running:  0
goroutine running: 1
goroutine running: 2
goroutine running: 3
Calling Function Returned Here
goroutine running: 4
goroutine running: 5
goroutine running: 6
goroutine running: 7
Main Function Returned Here

Program exited.

Special Thanks

I want to thank Chris Binder and Chase Isabelle for their valuable feedback on my post. Their comments and suggestions were instrumental in helping me correct the mistakes in my previous version. I am grateful for their insights and expertise, and for the opportunity to benefit from their valuable input. Thank you again for your invaluable contributions.

--

--

Nator Verinumbe
Nator Verinumbe

Written by Nator Verinumbe

Not afraid of hard work, taking risks and getting broke (maybe a little nowadays). Constantly trying, learning and trying again.