![]() |
![]() |
很重要--轉載聲明
- 本站文章無特別說明,皆爲原創,版權全部,轉載時請用連接的方式,給出原文出處。同時寫上原做者:朝十晚八 or Twowords
- 如要轉載,請原文轉載,如在轉載時修改本文,請事先告知,謝絕在轉載時經過修改本文達到有利於轉載者的目的。
goroutine
是一個輕量級的執行線程。假設有一個函數調用f(s)
,要在goroutine
中調用此函數,請使用go f(s)
。 這個新的goroutine
將與調用同時執行。html
示例代碼以下:golang
1 package main 2 3 import "fmt" 4 5 func f(from string) { 6 for i := 0; i < 3; i++ { 7 fmt.Println(from, ":", i) 8 } 9 } 10 11 func main() { 12 13 // Suppose we have a function call `f(s)`. Here's how 14 // we'd call that in the usual way, running it 15 // synchronously. 16 f("direct") 17 18 // To invoke this function in a goroutine, use 19 // `go f(s)`. This new goroutine will execute 20 // concurrently with the calling one. 21 go f("goroutine") 22 23 // You can also start a goroutine for an anonymous 24 // function call. 25 go func(msg string) { 26 fmt.Println(msg) 27 }("going") 28 29 // Our two function calls are running asynchronously in 30 // separate goroutines now, so execution falls through 31 // to here. This `Scanln` code requires we press a key 32 // before the program exits. 33 var input string 34 fmt.Scanln(&input) 35 fmt.Println("done") 36 }
執行上面代碼,將獲得如下輸出結果安全
1 direct : 0 2 direct : 1 3 direct : 2 4 goroutine : 0 5 goroutine : 1 6 goroutine : 2 7 going
通道是鏈接併發goroutine
的管道。能夠從一個goroutine
向通道發送值,並在另外一個goroutine
中接收到這些值。併發
1 package main 2 3 import "fmt" 4 5 func main() { 6 7 // Create a new channel with `make(chan val-type)`. 8 // Channels are typed by the values they convey. 9 messages := make(chan string) 10 11 // _Send_ a value into a channel using the `channel <-` 12 // syntax. Here we send `"ping"` to the `messages` 13 // channel we made above, from a new goroutine. 14 go func() { messages <- "ping" }()//使用"<-"向通道發送消息 15 16 // The `<-channel` syntax _receives_ a value from the 17 // channel. Here we'll receive the `"ping"` message 18 // we sent above and print it out. 19 msg := <-messages//"從通道讀取數據" 20 fmt.Println(msg) 21 }
默認狀況下,通道是未緩衝的,意味着若是有相應的接收(<- chan
)準備好接收發送的值,它們將只接受發送(chan <-
)。使用make的第二個參數指定緩衝大小yii
1 package main 2 3 import "fmt" 4 5 func main() { 6 7 // Here we `make` a channel of strings buffering up to 8 // 2 values. 9 messages := make(chan string, 2) 10 11 // Because this channel is buffered, we can send these 12 // values into the channel without a corresponding 13 // concurrent receive. 14 messages <- "buffered" 15 messages <- "channel" 16 17 // Later we can receive these two values as usual. 18 fmt.Println(<-messages) 19 fmt.Println(<-messages) 20 }
1 package main 2 3 import "fmt" 4 import "time" 5 6 // This is the function we'll run in a goroutine. The 7 // `done` channel will be used to notify another 8 // goroutine that this function's work is done. 9 func worker(done chan bool) { 10 fmt.Print("working...") 11 time.Sleep(time.Second) 12 fmt.Println("done") 13 14 // Send a value to notify that we're done. 15 done <- true 16 } 17 18 func main() { 19 20 // Start a worker goroutine, giving it the channel to 21 // notify on. 22 done := make(chan bool, 1) 23 go worker(done) 24 25 // Block until we receive a notification from the 26 // worker on the channel. 27 <-done 28 }
當使用通道做爲函數參數時,能夠指定通道是否僅用於發送或接收值。這種特殊性增長了程序的類型安全性。chan<-
表示發送,<-chan
表示接收async
每一個通道將在一段時間後開始接收值,以模擬阻塞在併發goroutines
中執行的RPC
操做。咱們將使用select
同時等待這兩個值,在每一個值到達時打印它們。函數
1 package main 2 3 import "time" 4 import "fmt" 5 6 func main() { 7 8 // For our example we'll select across two channels. 9 c1 := make(chan string) 10 c2 := make(chan string) 11 12 // Each channel will receive a value after some amount 13 // of time, to simulate e.g. blocking RPC operations 14 // executing in concurrent goroutines. 15 go func() { 16 time.Sleep(time.Second * 1) 17 c1 <- "one" 18 }() 19 go func() { 20 time.Sleep(time.Second * 2) 21 c2 <- "two" 22 }() 23 24 // We'll use `select` to await both of these values 25 // simultaneously, printing each one as it arrives. 26 for i := 0; i < 2; i++ { 27 select { 28 case msg1 := <-c1: 29 fmt.Println("received", msg1) 30 case msg2 := <-c2: 31 fmt.Println("received", msg2) 32 } 33 } 34 }
Go超時(timeouts)實例post
Go非阻塞通道操做實例:使用select
和default
子句來實現非阻塞發送,接收ui
Go關閉通道實例:close直接關閉通道this
Go通道範圍實例:通道關閉了,還能夠接收通道中的數據