最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

有了 select語(yǔ)句,可以實(shí)現(xiàn) main主線(xiàn)程 與 goroutine線(xiàn)程 之間的互動(dòng)。

1.基本語(yǔ)法

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

注意事項(xiàng)

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

(1)多個(gè)IO操作發(fā)生時(shí),case語(yǔ)句是隨機(jī)執(zhí)行的

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

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

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

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

(2)空select語(yǔ)句

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資源消耗過(guò)高

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

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

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

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

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

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

// 通過(guò)控制臺(tái)輸入 "bye", 來(lái)控制main函數(shù)結(jié)束運(yùn)行
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 {
?? ??? ?// 控制臺(tái)輸入
?? ??? ?fmt.Print("please input string: ")
?? ??? ?scanner := bufio.NewScanner(os.Stdin)
?? ??? ?scanner.Scan()
?? ??? ?ch <- scanner.Text()

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

運(yùn)行:

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

(2)超時(shí)實(shí)現(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("超時(shí)")
?? ??? ??? ??? ?quit <- true
?? ??? ??? ?}
?? ??? ?}
?? ?}()

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

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

相關(guān)文章

  • 云端golang開(kāi)發(fā),無(wú)需本地配置,能上網(wǎng)就能開(kāi)發(fā)和運(yùn)行

    云端golang開(kāi)發(fā),無(wú)需本地配置,能上網(wǎng)就能開(kāi)發(fā)和運(yùn)行

    這篇文章主要介紹了云端golang開(kāi)發(fā),無(wú)需本地配置,能上網(wǎng)就能開(kāi)發(fā)和運(yùn)行的相關(guān)資料,需要的朋友可以參考下
    2023-10-10
  • Go切片的具體使用

    Go切片的具體使用

    本文主要介紹了Go切片的具體使用,包括聲明切片、初始化切片、切片的切割、切片的添加、切片的刪除、切片的復(fù)制、切片的遍歷、多維切片等,感興趣的可以了解一下
    2023-11-11
  • Go語(yǔ)言使用sqlx操作數(shù)據(jù)庫(kù)的示例詳解

    Go語(yǔ)言使用sqlx操作數(shù)據(jù)庫(kù)的示例詳解

    sqlx?是?Go?語(yǔ)言中一個(gè)流行的第三方包,它提供了對(duì)?Go?標(biāo)準(zhǔn)庫(kù)?database/sql?的擴(kuò)展,本文重點(diǎn)講解?sqlx?在?database/sql?基礎(chǔ)上擴(kuò)展的功能,希望對(duì)大家有所幫助
    2023-06-06
  • Go語(yǔ)言題解LeetCode599兩個(gè)列表的最小索引總和

    Go語(yǔ)言題解LeetCode599兩個(gè)列表的最小索引總和

    這篇文章主要為大家介紹了Go語(yǔ)言題解LeetCode599兩個(gè)列表的最小索引總和示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • 詳解Go語(yǔ)言中rand(隨機(jī)數(shù))包的使用

    詳解Go語(yǔ)言中rand(隨機(jī)數(shù))包的使用

    在Golang中,有兩個(gè)包提供了rand,分別為math/rand和crypto/rand對(duì)應(yīng)兩種應(yīng)用場(chǎng)景。math/rand包實(shí)現(xiàn)了偽隨機(jī)數(shù)生成器。也就是生成 整形和浮點(diǎn)型;crypto/rand包實(shí)現(xiàn)了用于加解密的更安全的隨機(jī)數(shù)生成器。本文就來(lái)和大家詳細(xì)講講math/rand的使用
    2022-08-08
  • 使用Go實(shí)現(xiàn)健壯的內(nèi)存型緩存的方法

    使用Go實(shí)現(xiàn)健壯的內(nèi)存型緩存的方法

    這篇文章主要介紹了使用Go實(shí)現(xiàn)健壯的內(nèi)存型緩存,本文比較了字節(jié)緩存和結(jié)構(gòu)體緩存的優(yōu)劣勢(shì),介紹了緩存穿透、緩存錯(cuò)誤、緩存預(yù)熱、緩存?zhèn)鬏?、故障轉(zhuǎn)移、緩存淘汰等問(wèn)題,并對(duì)一些常見(jiàn)的緩存庫(kù)進(jìn)行了基準(zhǔn)測(cè)試,需要的朋友可以參考下
    2022-05-05
  • golang簡(jiǎn)單獲取上傳文件大小的實(shí)現(xiàn)代碼

    golang簡(jiǎn)單獲取上傳文件大小的實(shí)現(xiàn)代碼

    這篇文章主要介紹了golang簡(jiǎn)單獲取上傳文件大小的方法,涉及Go語(yǔ)言文件傳輸及文件屬性操作的相關(guān)技巧,需要的朋友可以參考下
    2016-07-07
  • 使用 Go 管理版本的方法示例

    使用 Go 管理版本的方法示例

    這篇文章主要介紹了使用 Go 管理版本的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • GoLang完整實(shí)現(xiàn)快速列表

    GoLang完整實(shí)現(xiàn)快速列表

    這篇文章主要介紹了GoLang完整實(shí)現(xiàn)快速列表,列表是一種非連續(xù)的存儲(chǔ)容器,由多個(gè)節(jié)點(diǎn)組成,節(jié)點(diǎn)通過(guò)一些 變量 記錄彼此之間的關(guān)系,列表有多種實(shí)現(xiàn)方法,如單鏈表、雙鏈表等
    2022-12-12
  • Golang仿ps實(shí)現(xiàn)獲取Linux進(jìn)程信息

    Golang仿ps實(shí)現(xiàn)獲取Linux進(jìn)程信息

    這篇文章主要為大家學(xué)習(xí)介紹了Golang如何仿ps實(shí)現(xiàn)獲取Linux進(jìn)程信息,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下
    2023-07-07

最新評(píng)論

广饶县| 呈贡县| 呼伦贝尔市| 黄平县| 龙门县| 高碑店市| 津南区| 铜陵市| 吴川市| 改则县| 左贡县| 连云港市| 陇川县| 永靖县| 北安市| 宜君县| 杭州市| 来安县| 蓬安县| 塔城市| 平陆县| 晋城| 互助| 榕江县| 广元市| 民权县| 永康市| 新巴尔虎右旗| 湘阴县| 清新县| 南雄市| 广丰县| 监利县| 绥化市| 同仁县| 九龙坡区| 澄城县| 镇原县| 奉节县| 泌阳县| 辉县市|