golang中的select和switch

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

select

golang的select功能和C中的select, poll, epoll類似,就是監聽 IO 操作,當 IO 操作發生時,觸發相應的動作。

ch1 := make (chan int, 1)ch2 := make (chan int, 1)select {case <-ch1:    fmt.Println("ch1 pop one element")case <-ch2:    fmt.Println("ch2 pop one element")}

select 的代碼形式和 switch 非常相似, 不過 select 的 case 裡的動作陳述式只能是【IO 操作】 。
此樣本裡面 select 會一直等待等到某個 case 陳述式完成, 也就是等到成功從 ch1 或者 ch2 中讀到資料。 則 select 語句結束。

使用 select 實現 timeout 機制

timeout := make (chan bool, 1)go func() {    time.Sleep(1e9) // sleep one second    timeout <- true}()ch := make (chan int) select {case <- ch:case <- timeout:    fmt.Println("timeout!")}

同時等待讀取ch和timeout,當逾時時間到的時候,<- timeout會操作成功。 所以 select 語句則會退出。 而不是一直阻塞在 ch 的讀取操作上。 從而實現了對 ch 讀取操作的逾時設定。
如果select包含default,則上述兩個都無法成功讀取的情況下,直接進入default。因此,可以在select中放入case ch <- 1,如果進入default條件,說明通道已經滿了。

注意點

  1. 沒有default時,select語句會一直等待,直到某個case裡的IO操作可以進行
  2. case條件中包含的【通道運算式】和【元素運算式】都會先被求值。無論它們所在的case是否有可能被選擇都會這樣。
  3. 如果有多個case同時可以運行,go會隨機播放一個case執行

switch

golang中switch有兩種判斷條件:運算式、類型(boolean-expression or integral type)

switch marks {    case 90: grade = "A"    case 80: grade = "B"    case 50,60,70 : grade = "C"    default: grade = "D" }switch {    case grade == "A" :        fmt.Printf("Excellent!\n" )         case grade == "B", grade == "C" :        fmt.Printf("Well done\n" )          case grade == "D" :        fmt.Printf("You passed\n" )          case grade == "F":        fmt.Printf("Better try again\n" )    default:        fmt.Printf("Invalid grade\n" );}switch i := x.(type) {    case nil:           fmt.Printf("type of x :%T",i)                    case int:           fmt.Printf("x is int")                                   case func(int) float64:        fmt.Printf("x is func(int)")                          case bool, string:        fmt.Printf("x is bool or string")           default:        fmt.Printf("don't know the type")     }  

使用select + switch實現 goroutine 控制

通過在一個goroutine中發送控制訊號控制其他goroutine的運行狀態,如暫停和運行

package mainimport (    "fmt"    "runtime"    "sync")// Possible worker states.const (    Stopped = 0    Paused  = 1    Running = 2)// Maximum number of workers.const WorkerCount = 1000func main() {    // Launch workers.    var wg sync.WaitGroup    wg.Add(WorkerCount + 1)    workers := make([]chan int, WorkerCount)    for i := range workers {        workers[i] = make(chan int, 1)        go func(i int) {            worker(i, workers[i])            wg.Done()        }(i)    }    // Launch controller routine.    go func() {        controller(workers)        wg.Done()    }()    // Wait for all goroutines to finish.    wg.Wait()}func worker(id int, ws <-chan int) {    state := Paused // Begin in the paused state.    for {        select {        case state = <-ws:            switch state {            case Stopped:                fmt.Printf("Worker %d: Stopped\n", id)                return            case Running:                fmt.Printf("Worker %d: Running\n", id)            case Paused:                fmt.Printf("Worker %d: Paused\n", id)            }        default:            // We use runtime.Gosched() to prevent a deadlock in this case.            // It will not be needed of work is performed here which yields            // to the scheduler.            runtime.Gosched()            if state == Paused {                break            }            // Do actual work here.        }    }}// controller handles the current state of all workers. They can be// instructed to be either running, paused or stopped entirely.func controller(workers []chan int) {    // Start workers    setState(workers, Running)    // Pause workers.    setState(workers, Paused)    // Unpause workers.    setState(workers, Running)    // Shutdown workers.    setState(workers, Stopped)}// setState changes the state of all given workers.func setState(workers []chan int, state int) {    for _, w := range workers {        w <- state    }}

注意,此處有坑!!!
使用該方法有可能導致程式在啟動時死結,並不能在controller中隨意的暫停和啟動。比如,一開始寫入 暫停 ,此時worker暫停,導致不能從worker chan中消費資料,導致controller不能向worker chan寫入run狀態(chan長度為1)
因此,在程式第一次執行到此處時,要注意對chan的控制

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.