This question already has an answer here:
I am new to Go language programming and learning it step by step.
While practicing it, I found random behavior of goroutines.
If I call goroutine (function having sleep of 1 second), some times it completed successfully and some times it doesn't:
package main
import (
"fmt"
"time"
)
func t(i int) {
fmt.Println("In func t")
time.Sleep(1)
}
func t1(i int) {
fmt.Println("In func t1")
time.Sleep(1)
}
func main() {
fmt.Println("Hello Good Morning")
go t(1)
t1(2)
time.Sleep(5)
fmt.Println("End of func main")
}
O/p 1 :
Hello Good Morning
In func t1
In func t
End of func main
O/p 2 :
Hello Good Morning
In func t1
End of func main
Could someone explain why goroutine is not guaranteeing the execution of that goroutine function call.
</div>
When the function
main
returns, the program exits. It does not wait for other (non-main) goroutines to complete.
1- main
is goroutine too, you need to wait for other goroutines to finish, and you may use
time.Sleep(5 * time.Second)
for 5 Seconds wait, try it on The Go Playground:
package main
import (
"fmt"
"time"
)
func t(i int) {
fmt.Println("In func t")
time.Sleep(1 * time.Second)
}
func t1(i int) {
fmt.Println("In func t1")
time.Sleep(1 * time.Second)
}
func main() {
fmt.Println("Hello Good Morning")
go t(1)
t1(2)
time.Sleep(5 * time.Second)
fmt.Println("End of func main")
}
output:
Hello Good Morning
In func t1
In func t
End of func main
And see Docs:
// Sleep pauses the current goroutine for at least the duration d. // A negative or zero duration causes Sleep to return immediately. func Sleep(d Duration)
2- You may use sync.WaitGroup
to wait for other goroutines, try it on The Go Playground:
package main
import (
"fmt"
"sync"
"time"
)
var w sync.WaitGroup
func say(s string) {
for i := 0; i < 2; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
w.Done()
}
func main() {
w.Add(1)
go say("A")
w.Add(1)
say("B")
w.Wait()
}
output:
B
A
A
B
Two things:
main
without having explicitly waited for your goroutine to finish, there's no guarantee that it will finish before the program exits.time.Sleep()
is time.Duration
, the units of which are nanoseconds. Since you're barely delaying at all, it's not surprising that your results were random. If you sleep for a more substantial amount of time in main
, you should see both lines printed (although it isn't guaranteed).If you need to wait for a goroutine to finish, there are various ways to do that (e.g, channels and sync.WaitGroup
).
You may want to go through A Tour of Go and/or take a look at Effective Go.