您好,登錄后才能下訂單哦!
這篇文章主要介紹“go語言中怎么使用select”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“go語言中怎么使用select”文章能幫助大家解決問題。
在golang語言中,select語句 就是用來監聽和channel有關的IO操作,當IO操作發生時,觸發相應的case動作。
有了 select語句,可以實現 main主線程 與 goroutine線程 之間的互動。
select { case <-ch2 : // 檢測有沒有數據可讀 // 一旦成功讀取到數據,則進行該case處理語句 case ch3 <- 1 : // 檢測有沒有數據可寫 // 一旦成功向ch3寫入數據,則進行該case處理語句 default: // 如果以上都沒有符合條件,那么進入default處理流程 }
注意事項
select語句 只能用于channel信道的IO操作,每個case都必須是一個信道。
如果不設置 default條件,當沒有IO操作發生時,select語句就會一直阻塞;
如果有一個或多個IO操作發生時,Go運行時會隨機選擇一個case執行,但此時將無法保證執行順序;
對于case語句,如果存在信道值為nil的讀寫操作,則該分支將被忽略,可以理解為相當于從select語句中刪除了這個case;
對于空的 select語句,會引起死鎖;
對于在 for中的select語句,不能添加 default,否則會引起cpu占用過高的問題;
(1)多個IO操作發生時,case語句是隨機執行的
func main() { ch2 := make(chan int, 1) // 創建 一個長度帶緩沖的整型通道 ch2 <- 1 // 向通道中寫入數據 ch3 := make(chan int, 1) ch3 <- 2 select { case <- ch2: fmt.Println("ch2 read") case <- ch3: fmt.Println("ch3 read") } }
多次執行后,會隨機打印 “ch2 read” 或 “ch3 read”
(2)空select語句
func main() { select { } }
執行后,引發死鎖,打印如下:
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循環中執行 return default: fmt.Println("default") } } }() time.Sleep(3 * time.Second) quit <- true // 主線程在3秒后,向quit信道寫入數據 time.Sleep(2 * time.Second) fmt.Println("main") }
在for{}的select語句中使用了 default后,線程就會無限執行default條件,直到quit信道中讀到數據,否則會一直在一個死循環中運行,從而導致占滿整個CPU資源。
在 for{}的select語句中,不建議使用 default條件。
(1)實現 main主線程與 goroutine線程 之間的交互、通信
// 通過控制臺輸入 "bye", 來控制main函數結束運行 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)超時實現
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 // 等待超時后, 結束 main主線程 fmt.Println("程序結束") }
關于“go語言中怎么使用select”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。