欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

go語言中如何使用select的實現(xiàn)示例

 更新時間:2022年05月13日 11:49:26   作者:grb123  
本文主要介紹了go語言中如何使用select的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

在golang語言中,select語句 就是用來監(jiān)聽和channel有關(guān)的IO操作,當IO操作發(fā)生時,觸發(fā)相應(yīng)的case動作。

有了 select語句,可以實現(xiàn) main主線程 與 goroutine線程 之間的互動。

1.基本語法

select {
    case <-ch1 :     // 檢測有沒有數(shù)據(jù)可讀
        // 一旦成功讀取到數(shù)據(jù),則進行該case處理語句
    case ch2 <- 1 :  // 檢測有沒有數(shù)據(jù)可寫
        // 一旦成功向ch2寫入數(shù)據(jù),則進行該case處理語句
    default:
        // 如果以上都沒有符合條件,那么進入default處理流程
}

注意事項

  • select語句 只能用于channel信道的IO操作,每個case都必須是一個信道。
  • 如果不設(shè)置 default條件,當沒有IO操作發(fā)生時,select語句就會一直阻塞;
  • 如果有一個或多個IO操作發(fā)生時,Go運行時會隨機選擇一個case執(zhí)行,但此時將無法保證執(zhí)行順序;
  • 對于case語句,如果存在信道值為nil的讀寫操作,則該分支將被忽略,可以理解為相當于從select語句中刪除了這個case;
  • 對于空的 select語句,會引起死鎖;
  • 對于在 for中的select語句,不能添加 default,否則會引起cpu占用過高的問題;

(1)多個IO操作發(fā)生時,case語句是隨機執(zhí)行的

func main() ?{
?? ?ch1 := make(chan int, 1) ? // 創(chuàng)建 一個長度帶緩沖的整型通道
?? ?ch1 <- 1 ? ? ? ? ? ? ? ? ? // 向通道中寫入數(shù)據(jù)

?? ?ch2 := make(chan int, 1)
?? ?ch2 <- 2

?? ?select {
?? ? ? ?case <- ch1:
?? ? ? ??? ?fmt.Println("ch1 read")
?? ??? ?case <- ch2:
?? ??? ??? ?fmt.Println("ch2 read")
?? ?}
}

多次執(zhí)行后,會隨機打印 “ch1 read” 或 “ch2 read”

(2)空select語句

func main()  {
    select {
    
    }
}

執(zhí)行后,引發(fā)死鎖,打印如下:

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [select (no cases)]:
main.main()
        xxx/test.go:4 +0x27
exit status 2

(3)for中的select 引起CPU資源消耗過高

func main() ?{
?? ?quit := make(chan bool)
?? ?go func() {
?? ??? ?for {
?? ??? ??? ?select {
?? ??? ??? ?case <-quit:
?? ??? ??? ??? ?fmt.Println("quit")
?? ??? ??? ??? ?// 使用 return 就會退出整個goroutine線程;如果使用 break,程序仍然在for循環(huán)中執(zhí)行
?? ??? ??? ??? ?return
?? ??? ??? ?default:
?? ??? ??? ??? ?fmt.Println("default")
?? ??? ??? ?}
?? ??? ?}
?? ?}()

?? ?time.Sleep(3 * time.Second)
?? ?quit <- true ? ? ? ? ?// 主線程在3秒后,向quit信道寫入數(shù)據(jù)
?? ?
?? ?time.Sleep(2 * time.Second)
?? ?fmt.Println("main")
}

在for{}的select語句中使用了 default后,線程就會無限執(zhí)行default條件,直到quit信道中讀到數(shù)據(jù),否則會一直在一個死循環(huán)中運行,從而導(dǎo)致占滿整個CPU資源。

在 for{}的select語句中,不建議使用 default條件。

2.select語句的實際應(yīng)用

(1)實現(xiàn) main主線程與 goroutine線程 之間的交互、通信

// 通過控制臺輸入 "bye", 來控制main函數(shù)結(jié)束運行
func main() ?{
?? ?quit := make(chan bool)
?? ?ch := make(chan string)

?? ?go func() {
?? ??? ?for {
?? ??? ??? ?select {
?? ??? ??? ?case name := <-ch:
?? ??? ??? ??? ?fmt.Printf("from main msg: [%v]\n", name)
?? ??? ??? ??? ?if name == "bye" {
?? ??? ??? ??? ??? ?quit <- true
?? ??? ??? ??? ?} else {
?? ??? ??? ??? ??? ?quit <- false
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
?? ?}()

?? ?for {
?? ??? ?// 控制臺輸入
?? ??? ?fmt.Print("please input string: ")
?? ??? ?scanner := bufio.NewScanner(os.Stdin)
?? ??? ?scanner.Scan()
?? ??? ?ch <- scanner.Text()

?? ??? ?isOver := <- quit
?? ??? ?if isOver {
?? ??? ??? ?break
?? ??? ?}
?? ?}
?? ?fmt.Println("main over")
}

運行:

from main msg: [aaa]
please input string: bbb
from main msg: [bbb]
please input string: bye
from main msg: [bye]
main over

(2)超時實現(xiàn)

func main() ?{
?? ?quit := make(chan bool)
?? ?ch := make(chan int)

?? ?go func() {
?? ??? ?for {
?? ??? ??? ?select {
?? ??? ??? ?case num := <- ch:
?? ??? ??? ??? ?fmt.Println("num = ", num)
?? ??? ??? ?case <- time.After(5 * time.Second):
?? ??? ??? ??? ?fmt.Println("超時")
?? ??? ??? ??? ?quit <- true
?? ??? ??? ?}
?? ??? ?}
?? ?}()

?? ?for i := 0; i < 2; i++ {
?? ??? ?ch <- i
?? ??? ?time.Sleep(time.Second)
?? ?}
?? ?<- quit ? ? ? ? ? ? ? ? ? // 等待超時后, 結(jié)束 main主線程
?? ?fmt.Println("程序結(jié)束")
}

到此這篇關(guān)于go語言中如何使用select的實現(xiàn)示例的文章就介紹到這了,更多相關(guān)go語言使用select內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go 實現(xiàn)百萬WebSocket連接的方法示例

    Go 實現(xiàn)百萬WebSocket連接的方法示例

    這篇文章主要介紹了Go 實現(xiàn)百萬WebSocket連接的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • GoFrame?gmap遍歷hashmap?listmap?treemap使用技巧

    GoFrame?gmap遍歷hashmap?listmap?treemap使用技巧

    這篇文章主要為大家介紹了GoFrame?gmap遍歷hashmap?listmap?treemap使用技巧的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • Go語言開發(fā)保證并發(fā)安全實例詳解

    Go語言開發(fā)保證并發(fā)安全實例詳解

    這篇文章主要為大家介紹了Go語言開發(fā)保證并發(fā)安全實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • Go語言工程實踐單元測試基準測試示例詳解

    Go語言工程實踐單元測試基準測試示例詳解

    這篇文章主要為大家介紹了Go語言工程實踐單元測試基準測試示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • golang的空標識符理解

    golang的空標識符理解

    今天小編就為大家分享一篇關(guān)于golang的空標識符理解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • Skywalking-go自動監(jiān)控增強使用探究

    Skywalking-go自動監(jiān)控增強使用探究

    這篇文章主要介紹了Skywalking-go自動監(jiān)控增強使用深入探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2024-01-01
  • 淺談Golang?Slice切片如何擴容的實現(xiàn)

    淺談Golang?Slice切片如何擴容的實現(xiàn)

    本文主要介紹了淺談Golang?Slice切片如何擴容的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • GoFrame?gtree樹形結(jié)構(gòu)的使用技巧示例

    GoFrame?gtree樹形結(jié)構(gòu)的使用技巧示例

    這篇文章主要為大家介紹了GoFrame?gtree樹形結(jié)構(gòu)的使用技巧示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • golang之log rotate詳解

    golang之log rotate詳解

    下面小編就為大家?guī)硪黄猤olang之log rotate詳解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • 基于Go語言搭建靜態(tài)文件服務(wù)器的詳細教程

    基于Go語言搭建靜態(tài)文件服務(wù)器的詳細教程

    Go 是一個開源的編程語言,它能讓構(gòu)造簡單、可靠且高效的軟件變得容易,本文給大家介紹了基于Go語言搭建靜態(tài)文件服務(wù)器的詳細教程,文中通過圖文和代碼講解的非常詳細,需要的朋友可以參考下
    2024-10-10

最新評論