觀察常規代碼和併發代碼的輸出順序。併發
// 常規代碼,順序執行,依次輸出 package main import ( "fmt" "time" ) func main() { strN := []string{"a", "b", "c", "d"} for _, strV := range strN { time.Sleep(time.Second) fmt.Println(strV) } intN := []int{1, 2, 3, 4} for _, intV := range intN { time.Sleep(time.Second) fmt.Println(intV) } }
// 併發代碼,併發執行,無序輸出 package main import ( "fmt" "time" ) func main() { go func() { strN := []string{"a", "b", "c", "d"} for _, strV := range strN { time.Sleep(time.Second) fmt.Println(strV) } }() go func() { intN := []int{1, 2, 3, 4} for _, intV := range intN { time.Sleep(time.Second) fmt.Println(intV) } }() // 防止main routine過早退出 time.Sleep(10 * time.Second) }
// 生產者關閉通道 package main import ( "time" "fmt" ) func main() { channel := make(chan string) go func() { names := []string{"Jack", "Mike", "John", "Kitty"} for _, name := range names { time.Sleep(time.Second) // fmt.Println(name) channel <- name } // 發送完畢關閉通道,不然引發死鎖 close(channel) }() for data := range channel { fmt.Println(data) } }
// 利用無緩衝通道同步傳遞數據 package main import "fmt" func main(){ nameChannel := make(chan string) done := make(chan string) go func(){ names := []string {"tarik", "michael", "gopi", "jessica"} for _, name := range names { fmt.Println("Processing the first stage of: " + name) nameChannel <- name } close(nameChannel) }() go func(){ for name := range nameChannel{ fmt.Println("Processing the second stage of: " + name) } done <- "" }() <-done }
// 利用有緩衝通道傳遞數據,提升性能 package main import "fmt" func main(){ nameChannel := make(chan string, 5) done := make(chan string) go func(){ names := []string {"tarik", "michael", "gopi", "jessica"} for _, name := range names { fmt.Println("Processing the first stage of: " + name) nameChannel <- name } close(nameChannel) }() go func(){ for name := range nameChannel{ fmt.Println("Processing the second stage of: " + name) } done <- "" }() <-done }
package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup for i := 0; i < 10; i++ { // 遍歷一次,增長一次計數 wg.Add(1) go func(){ fmt.Println("Hello World") // 執行一次,減小一次計數 wg.Done() }() } // 等待計數歸零,結束程序 wg.Wait() }
// 利用通道等待 package main import ( "time" "fmt" ) func main() { channel := make(chan string) go func() { names := []string{"Jack", "Mike", "John", "Kitty"} for _, name := range names { time.Sleep(time.Second) fmt.Println(name) // channel <- name } // 遍歷完畢向通道發送數據,告訴main routine已執行完畢 channel <- "" }() // main routine收到數據,退出程序 // 由於只是爲了同步,不須要通道中的數據,因此將數據拋棄 <-channel }
package main import ( "time" "fmt" ) func main() { channel1 := make(chan string) channel2 := make(chan string) go func(){ time.Sleep(1*time.Second) channel1 <- "Hello from channel1" }() go func(){ time.Sleep(1 * time.Second) channel2 <- "Hello from channel2" }() var result string // select隨機選擇知足條件的case select { case result = <-channel1: fmt.Println(result) case result = <-channel2: fmt.Println(result) } }