超時(shí)對(duì)于連接到外部資源或在不需要綁定執(zhí)行時(shí)間的程序很重要。在Go編程中由于使用了通道和選擇(select),實(shí)現(xiàn)超時(shí)是容易和優(yōu)雅的。
在這個(gè)示例中,假設(shè)正在執(zhí)行一個(gè)外部調(diào)用,2秒后在通道c1上返回其結(jié)果。
這里是 select 實(shí)現(xiàn)超時(shí)。 res:= <-c1等待結(jié)果和<-Time。等待在超時(shí)1秒后發(fā)送一個(gè)值。 由于選擇繼續(xù)準(zhǔn)備好第一個(gè)接收,如果操作超過(guò)允許的1秒,則將按超時(shí)情況處理。
如果允許更長(zhǎng)的超時(shí),如:3s,那么從c2的接收將成功,這里將會(huì)打印結(jié)果。
運(yùn)行此程序顯示第一個(gè)操作超時(shí)和第二個(gè)操作超時(shí)。
使用此選擇超時(shí)模式需要通過(guò)通道傳達(dá)結(jié)果。這是一個(gè)好主意,因?yàn)槠渌匾?code>Go功能是基于渠道和Select?,F(xiàn)在看看下面的兩個(gè)例子:計(jì)時(shí)器和ticker。
所有的示例代碼,都放在
F:\worksp\golang目錄下。安裝Go編程環(huán)境請(qǐng)參考:http://www.yiibai.com/go/go_environment.html
timeouts.go的完整代碼如下所示 -
package main
import "time"
import "fmt"
func main() {
// For our example, suppose we're executing an external
// call that returns its result on a channel `c1`
// after 2s.
c1 := make(chan string, 1)
go func() {
time.Sleep(time.Second * 2)
c1 <- "result 1"
}()
// Here's the `select` implementing a timeout.
// `res := <-c1` awaits the result and `<-Time.After`
// awaits a value to be sent after the timeout of
// 1s. Since `select` proceeds with the first
// receive that's ready, we'll take the timeout case
// if the operation takes more than the allowed 1s.
select {
case res := <-c1:
fmt.Println(res)
case <-time.After(time.Second * 1):
fmt.Println("timeout 1")
}
// If we allow a longer timeout of 3s, then the receive
// from `c2` will succeed and we'll print the result.
c2 := make(chan string, 1)
go func() {
time.Sleep(time.Second * 2)
c2 <- "result 2"
}()
select {
case res := <-c2:
fmt.Println(res)
case <-time.After(time.Second * 3):
fmt.Println("timeout 2")
}
}
執(zhí)行上面代碼,將得到以下輸出結(jié)果 -
F:\worksp\golang>go run timeouts.go
timeout 1
result 2