併發中的select

2021-10-08 18:09:41 字數 2070 閱讀 1681

select語句不使用default分支時,處於阻塞狀態直到其中乙個channel的收/發操作準備就緒(或者channel關閉或者緩衝區有值),如果同時有多個channel的收/發操作準備就緒(或者channel關閉)則隨機選擇其中乙個。

select語句使用default分支時,處於非阻塞狀態,從所有準備就緒(或者channel關閉或者緩衝區有值)的channel中隨機選擇其中乙個,如果沒有則執行default分支。

嚴格來講,select的實現包括兩種順序:一是:輪詢順序(poll order),二是加鎖/解鎖順序(lock order)。個人理解,這道題的本意應該是在問輪詢順序。

輪詢順序的實現: 首先將所有case分支進行隨機排序,然後按照這個隨機順序來遍歷case分支,選擇第乙個符合條件(就緒或關閉或緩衝區有值)的channel即返回不再遍歷後面的case分支。

在 for switch 和 for select 的 block中,如果用了break

break出的是switch 和 select ,並不是break for

解決方法:

1 用 return

2 用 break tag

package main

import

"fmt"

func

main()

} fmt.

println

("out!"

)}

package main

import

("fmt"

"time"

)func

main()

(ch1)

gofunc

(c2 chan

int)

(ch2)

//等10毫秒,確保兩個channel都已準備就緒

time.

sleep(10

* time.millisecond)

var index int

select

} fmt.

printf

("cnt=%v\n"

, cnt)

}

out:

cnt=

[497 503]

可以看出總和為1000,而且比例接近1:1(隨機)

package main

import

("fmt"

"time"

)func

main()

} fmt.

printf

("cnt=%v\n"

, cnt)

}

out:

cnt=

[512 488]

由於等待時間的存在,select還是在兩個分支中進行隨機選擇,不走default流程;但是如果去掉等待時間,將變為

cnt=

[0 0]

package main

import

"fmt"

func

fibonacci

(c, quit chan

int)}}

func

main()

quit<-0}

()// 無快取channel通訊必須要在不同的goroutine中,否則無法滿足乙個產生乙個消費的同步原則

fibonacci

(c,quit)

}

out:

112

35813

2134

55quit

package main

import

"time"

import

."fmt"

func

main()

}()go

func()

}}()

<- o

}

該程式輸出0-99,過5s後列印出timeout

Golang併發程式設計中select簡單了解

select可以監聽channel的資料流動 select的用法與switch語法非常類似,由select開始的乙個新的選擇塊,每個選擇條件由case語句來描述 與switch語句可以選擇任何使用相等比較的條件相比,select由比較多的限制,其中最大的一條限制就是每個case語句裡必須是乙個io操...

Go併發程式設計 select的使用

本文描述了select的用法,通過select可以監聽多個channel的讀寫事件。這很類似於linux系統程式設計的select函式。但在go中,實現的機制明顯是不同的。linux系統程式設計的select是輪訓的機制,而且監控的是檔案描述符,且有數量的限制。go中的select和channel配...

Golang併發模型 select高階

最近公司工作有點多,golang的select高階就這樣被拖沓啦,今天堅持把時間擠一擠,把吹的牛皮補上。前一篇文章 golang併發模型 輕鬆入門select 介紹了select的作用和它的基本用法,這次介紹它的3個高階特性。nil的通道永遠阻塞 如何跳出for selectselect 阻塞 當c...