溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

golang中select和超時

發(fā)布時間:2020-04-28 09:51:36 來源:網(wǎng)絡 閱讀:1675 作者:ck_god 欄目:編程語言

select作用

Go里面提供了一個關鍵字select,通過select可以監(jiān)聽channel上的數(shù)據(jù)流動。

 

select的用法與switch語言非常類似,由select開始一個新的選擇塊,每個選擇條件由case語句來描述。

 

switch語句可以選擇任何可使用相等比較的條件相比, select有比較多的限制,其中最大的一條限制就是每個case語句里必須是一個IO操作,大致的結構如下:

    select {

    case <-chan1:

        // 如果chan1成功讀到數(shù)據(jù),則進行該case處理語句

    case chan2 <- 1:

        // 如果成功向chan2寫入數(shù)據(jù),則進行該case處理語句

    default:

        // 如果上面都沒有成功,則進入default處理流程

    }

 

在一個select語句中,Go語言會按順序從頭至尾評估每一個發(fā)送和接收的語句。

 

如果其中的任意一語句可以繼續(xù)執(zhí)行(即沒有被阻塞),那么就從那些可以執(zhí)行的語句中任意選擇一條來使用。

 

如果沒有任意一條語句可以執(zhí)行(即所有的通道都被阻塞),那么有兩種可能的情況:

如果給出了default語句,那么就會執(zhí)行default語句,同時程序的執(zhí)行會從select語句后的語句中恢復。

如果沒有default語句,那么select語句將被阻塞,直到至少有一個通信可以進行下去。

 

示例代碼:

func fibonacci(c, quit chan int) {

    x, y := 1, 1

    for {

        select {

        case c <- x:

            x, y = y, x+y

        case <-quit:

            fmt.Println("quit")

            return

        }

}

 

 

 

}

 

func main() {

    c := make(chan int)

    quit := make(chan int)

 

    go func() {

        for i := 0; i < 6; i++ {

            fmt.Println(<-c)

        }

        quit <- 0

    }()

 

    fibonacci(c, quit)

}

 

運行結果如下:

golang中select和超時 

 

超時

有時候會出現(xiàn)goroutine阻塞的情況,那么我們如何避免整個程序進入阻塞的情況呢?我們可以利用select來設置超時,通過如下的方式實現(xiàn):

func main() {

    c := make(chan int)

    o := make(chan bool)

    go func() {

        for {

            select {

            case v := <-c:

                fmt.Println(v)

            case <-time.After(5 * time.Second):

                fmt.Println("timeout")

                o <- true

                break

            }

        }

    }()

    //c <- 666 // 注釋掉,引發(fā) timeout

    <-o

}


代碼如下所示:

// code_049_select_and_timeout project main.go
package main

import (
    "fmt"
    "time"
)

/*
1)Go里面提供了一個關鍵字select,通過select可以監(jiān)聽channel上的數(shù)據(jù)流動。

2)select的用法與switch語言非常類似,由select開始一個新的選擇塊,每個選擇條件由case語句來描述。

3)與switch語句可以選擇任何可使用相等比較的條件相比, select有比較多的限制,其中最大的一條限制就是每個case語句里必須是一個IO操作
*/

func fibonacci(c, quit chan int) {
    x, y := 1, 1
    for {
        select {
        case c <- x: //此處執(zhí)行了發(fā)送,如果成功向c寫入數(shù)據(jù),則進行該case處理語句
            x, y = y, x+y
        case <-quit: //此處執(zhí)行了接收, 如果quit成功讀到數(shù)據(jù),則進行該case處理語句
            //從輸出結果可以看到, 此代碼一直不斷地向channel中寫入數(shù)據(jù)。 在main函數(shù)中只是讀取6個數(shù)據(jù), 而寫入的數(shù)據(jù)多于讀取的數(shù)據(jù)
            fmt.Println("quit:y=", y)
            return
        }
    }
}

func main() {
    //1) select的使用
    c1 := make(chan int)
    quit := make(chan int)

    go func() {
        for i := 0; i < 6; i++ {
            fmt.Println(<-c1) //讀取數(shù)據(jù)
        }
        quit <- 0
    }()

    fibonacci(c1, quit)

    //2) goroutine阻塞,利用select設置超時
    c := make(chan int)
    o := make(chan bool)
    go func() {
        for {
            select {
            case v := <-c:
                fmt.Println(v)
            case <-time.After(5 * time.Second): //返回值為channel類型,輸出值為Time當前時間
                fmt.Println("timeout")
                o <- true
                break
            }
        }
    }()
    //c <-666 //注釋掉,引發(fā)timeout
    <-o
}


向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI