佳木斯湛栽影视文化发展公司

主頁(yè) > 知識(shí)庫(kù) > Golang的select多路復(fù)用及channel使用操作

Golang的select多路復(fù)用及channel使用操作

熱門(mén)標(biāo)簽:AI電銷(xiāo) 呼叫中心市場(chǎng)需求 網(wǎng)站排名優(yōu)化 百度競(jìng)價(jià)排名 服務(wù)外包 鐵路電話(huà)系統(tǒng) Linux服務(wù)器 地方門(mén)戶(hù)網(wǎng)站

看到有個(gè)例子實(shí)現(xiàn)了一個(gè)類(lèi)似于核彈發(fā)射裝置,在發(fā)射之前還是需要隨時(shí)能輸入終止發(fā)射。

這里就可以用到cahnnel 配合select 實(shí)現(xiàn)多路復(fù)用。

select的寫(xiě)法用法有點(diǎn)像switch。但是和switch不同的是,select的一個(gè)case代表一個(gè)通信操作(在某個(gè)channel上進(jìn)行發(fā)送或者接收)并且會(huì)包含一些語(yǔ)句組成的一個(gè)語(yǔ)句塊。現(xiàn)在讓我們來(lái)實(shí)現(xiàn)一下這個(gè)核彈發(fā)射器

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()
}

首先打印了一個(gè)commencing countdown開(kāi)始進(jìn)行倒數(shù)計(jì)時(shí)。

申明一個(gè)int類(lèi)型的 channel變量abort 用來(lái)做取消時(shí)候傳遞給select的消息信號(hào)量這個(gè)后面會(huì)介紹到。

申明一個(gè)int類(lèi)型的 channel變量canLunch 用來(lái)做倒計(jì)時(shí)結(jié)束可以發(fā)射的信號(hào)量。 只有當(dāng)?shù)箶?shù)結(jié)束,且canLunch有值后才能進(jìn)行發(fā)射。

用一個(gè)goroutine開(kāi)啟一個(gè)用于監(jiān)聽(tīng)是否有停止發(fā)射信號(hào)的函數(shù)isAbort并且把申明好的channel變量傳入。

isAbort就干一件事情,監(jiān)聽(tīng)是否有標(biāo)準(zhǔn)輸入輸入,如果有輸入我們默認(rèn)是下達(dá)了發(fā)射停止的信號(hào) 需要向abort channel里面發(fā)送一個(gè)信號(hào)。這里我們會(huì)發(fā)射一個(gè)-1

用一個(gè)goroutine開(kāi)啟一個(gè)用于倒數(shù)計(jì)時(shí)的函數(shù)commencingCountDown負(fù)責(zé)開(kāi)始倒計(jì)時(shí),這里重新申明了一個(gè) TICK channel 每一秒倒數(shù)計(jì)時(shí)一下。并且在倒數(shù)計(jì)時(shí)完成之后向canLunch channel發(fā)送信號(hào)。

然后開(kāi)始執(zhí)行select,select在沒(méi)有就緒的channel的時(shí)候會(huì)阻塞或者執(zhí)行指定的defualt,這里我沒(méi)有寫(xiě)default所以他會(huì)阻塞監(jiān)聽(tīng)兩個(gè)信號(hào),一個(gè)是canLunch,一個(gè)是停止發(fā)送。只要收到任何一個(gè)信號(hào)后,執(zhí)行該信號(hào)后面的內(nèi)容

最后運(yùn)行Lunch函數(shù)。

其實(shí)把思路理清楚,以并發(fā)的思考方式去思考這類(lèi)問(wèn)題感覺(jué)還是不會(huì)太亂。多加練習(xí)應(yīng)該會(huì)變好。下面的文章應(yīng)該會(huì)開(kāi)始逐步開(kāi)始從服務(wù)器和連接開(kāi)始,實(shí)現(xiàn)一個(gè)im系統(tǒng)?;蛘咛砑痈嗟膶?shí)踐。

補(bǔ)充:golang 使用select完成超時(shí)

我就廢話(huà)不多說(shuō)了,大家還是直接看代碼吧~

timeout := make(chan bool, 1)
go func() {
 time.Sleep(1e9)
 timeout - true
} ()
 
select {
 case - ch:
  //從ch中讀取數(shù)據(jù)
 case -timeout:
  //ch一直沒(méi)有數(shù)據(jù)寫(xiě)入,超時(shí)觸發(fā)timeout
}
func main() {
 var a chan string
 a =make(chan string)
 go sendDataTo(a)
 go timing()
 getAchan(10*time.Second,a) 
}
 
func sendDataTo(a chan string) {
 for {
   a - "我是a通道的數(shù)據(jù)"
  time.Sleep(1e9 *3)
 }
}
 
//在一定時(shí)間內(nèi)接收不到a的數(shù)據(jù)則超時(shí)
func getAchan(timeout time.Duration, a chan string) {
 var after -chan time.Time
 loop:
 after = time.After(timeout)
 for{
  fmt.Println("等待a中的數(shù)據(jù),10秒后沒(méi)有數(shù)據(jù)則超時(shí)")
  select {
  case x :=- a:
   fmt.Println(x)
   goto loop
  case -after:
   fmt.Println("timeout.")
   return
  }
 }
}
func timing() {
 //定時(shí)器,10秒鐘執(zhí)行一次
 ticker := time.NewTicker(10 * time.Second)
 for {
  time := -ticker.C
  fmt.Println("定時(shí)器====>",time.String())
 }
} 

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。

您可能感興趣的文章:
  • Golang實(shí)現(xiàn)Directional Channel(定向通道)
  • 詳解Golang中Channel的用法
  • golang開(kāi)發(fā)中channel使用
  • 基于golang channel實(shí)現(xiàn)的輕量級(jí)異步任務(wù)分發(fā)器示例代碼
  • golang中for循環(huán)遍歷channel時(shí)需要注意的問(wèn)題詳解
  • golang 函數(shù)返回chan類(lèi)型的操作

標(biāo)簽:蘭州 衡水 銅川 湖南 湘潭 仙桃 黃山 崇左

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Golang的select多路復(fù)用及channel使用操作》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話(huà)咨詢(xún)

    • 400-1100-266
    依兰县| 巴楚县| 桃源县| 汝州市| 阜康市| 富顺县| 西华县| 荔浦县| 古蔺县| 高州市| 东阿县| 淮北市| 松原市| 汉寿县| 鄂伦春自治旗| 剑川县| 长葛市| 广平县| 临清市| 阿克苏市| 建湖县| 卫辉市| 成都市| 昭苏县| 崇礼县| 永定县| 金山区| 沂水县| 东阿县| 黑河市| 延庆县| 鹤庆县| 武汉市| 常德市| 五大连池市| 郧西县| 肥东县| 呼图壁县| 云龙县| 高清| 东宁县|