Golang的select多路復用以及channel使用實踐


看到有個例子實現了一個類似於核彈發射裝置,在發射之前還是需要隨時能輸入終止發射。

這里就可以用到cahnnel 配合select 實現多路復用。

select的寫法用法有點像switch。但是和switch不同的是,select的一個case代表一個通信操作(在某個channel上進行發送或者接收)並且會包含一些語句組成的一個語句塊。現在讓我們來實現一下這個核彈發射器

package main

import (
    "fmt"
    "time"
    "os"
)

func launch() {
    fmt.Println("nuclear launch detected")
}

func commencingCountDown(canLunch chan int) {
    c := time.Tick(1 * time.Second)
    for countDown := 20; countDown > 0; countDown-- {
        fmt.Println(countDown)
        <- c
    }
    canLunch <- -1
}

func isAbort(abort chan int) {
    os.Stdin.Read(make([]byte, 1))
    abort <- -1
}

func main() {
    fmt.Println("Commencing coutdown")

    abort := make(chan int)
    canLunch := make(chan int)
    go isAbort(abort)
    go commencingCountDown(canLunch)
    select {
    case <- canLunch:

    case <- abort:
        fmt.Println("Launch aborted!")
        return
    }
    launch()
}

首先打印了一個commencing countdown開始進行倒數計時。

申明一個int類型的 channel變量abort 用來做取消時候傳遞給select的消息信號量這個后面會介紹到。

申明一個int類型的 channel變量canLunch 用來做倒計時結束可以發射的信號量。 只有當倒數結束,且canLunch有值后才能進行發射。

 

用一個goroutine開啟一個用於監聽是否有停止發射信號的函數isAbort並且把申明好的channel變量傳入。

isAbort就干一件事情,監聽是否有標准輸入輸入,如果有輸入我們默認是下達了發射停止的信號 需要向abort channel里面發送一個信號。這里我們會發射一個-1

 

用一個goroutine開啟一個用於倒數計時的函數commencingCountDown負責開始倒計時,這里重新申明了一個 TICK channel 每一秒倒數計時一下。並且在倒數計時完成之后向canLunch channel發送信號。

 

然后開始執行select,select在沒有就緒的channel的時候會阻塞或者執行指定的defualt,這里我沒有寫default所以他會阻塞監聽兩個信號,一個是canLunch,一個是停止發送。只要收到任何一個信號后,執行該信號后面的內容

 

最后運行Lunch函數。

其實把思路理清楚,以並發的思考方式去思考這類問題感覺還是不會太亂。多加練習應該會變好。下面的文章應該會開始逐步開始從服務器和連接開始,實現一個im系統。或者添加更多的實踐。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM