Why is time.sleep required to run certain goroutines?
Because the goroutine scheduler is not preemptive, your goroutines have to give up control before another goroutine will run. One way to give up control is with time.Sleep
. Another way is with runtime.Gosched()
.
Here's the tutorial modified to use Gosched(): http://play.golang.org/p/jQ9mlGYXXE
This is a useful lesson in understanding goroutines. However, trying to control the scheduler directly is definitely an anti-pattern; grief will often follow.
Instead, think more about the goroutines like chunks of communicating digital hardware (state machines are a good analogy). It's better to learn about the Communicating Sequential Processes model on which goroutines are based. In a CSP-based design, each goroutine has its own private state and exchanges messages to interact with the state of other goroutines. The passing of messages forces synchronization, which the scheduler uses to determine what activity gets cpu time and what gets put in a wait queue.
When you approach Go this way, you probably never need to worry about scheduler internals.
If you remove the time.Sleep
you don't give the say("world")
goroutine a chance to run. The goroutine scheduler is not preemptive. Your goroutines have to give up control before another goroutine will run. One way to give up control is to run time.Sleep
.
If you take out the time.Sleep
from the say
function then the primary goroutine runs 5 times without giving up control to the secondary goroutine and then when the primary goroutine returns from say
the program exits because there is nothing to keep the program alive.