In the GO tutorial, we have this slide: Goroutines
package main
import (
\"fmt\"
\"time\"
)
func say(s string) {
for i := 0; i < 5; i++ {
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.