直接上代码:

1. 第一种情况, 如果没有select{}, main 主线程不会等待coroutine运行,导致coroutine得不到机会运行。

You are requesting eventual scheduling (using the two go statements) 
of two goroutines and then you exit main without giving the scheduler 
a chance to do anything. 

有了select, 程序正常运行。

package main

import (
	"fmt"
        "time"
)


func main() {
	go func1()
	go func2()
	select{}
}

func func1() {
       for{
	    fmt.Println("here1")
            time.Sleep(10 * time.Minute)
        }

}

func func2() {
       for{
	   fmt.Println("here2")
           time.Sleep(10 * time.Minute)
       }
}

2. coroutine有机会运行,但是会发生死锁, fatal error: all goroutines are asleep - deadlock!

The goroutine executing func1 exited, ditto for func2. The main goroutine is blocked with no hope to recover while no other goroutine can be scheduled.

package main

import (
	"fmt"
	//"time"
)

func main() {
	go func1()
	go func2()
	select {
	}
}

func func1() {
	fmt.Println("here1")

}

func func2() {
	fmt.Println("here2")
}


3. 第三种情况, 正常运行。

package main

import (
	"fmt"
)

var c = make(chan int, 2)

func main() {
	go func1()
	go func2()
	<-c
	<-c
	fmt.Println("ok")
}

func func1() {
	fmt.Println("here1")
	c <- 1
}

func func2() {
	fmt.Println("here2")
	c <- 1
}

4. 实现上面的目的的另外一种方法:

  var wg sync.WaitGroup
    var urls = []string{
            "http://www.golang.org/",
            "http://www.google.com/",
            "http://www.somestupidname.com/",
    }
    for _, url := range urls {
            // Increment the WaitGroup counter.
            wg.Add(1)
            // Launch a goroutine to fetch the URL.
            go func(url string) {
                    // Decrement the counter when the goroutine completes.
                    defer wg.Done()
                    // Fetch the URL.
                    http.Get(url)
            }(url)
    }
    // Wait for all HTTP fetches to complete.
    wg.Wait()