Go Concurrency Patterns: Timing out, moving on
原文地址:https://blog.golang.org/concurrency-timeouts
并發變成有它自己的風格. 一個非常好的例子就是 timeout. 雖然 go 的 channel 沒有直接支持 timeout 機制,但是要實現它非常容易.
比如說,我們想從一個 channel ch 中接收數據,但是最多只想等待 1 秒. 我們可以這么做:創建一個 channel 作為信號 channel (signalling channel), 再創建一個 goroutine,這個 goroutine 再發送數據之前先休眠 1 秒.
timeout := make(chan bool, 1) go func() {time.Sleep(1 * time.Second)timeout <- true }()然后,我們使用 select 語句來從 ch 上接受數據. 如果在 1 秒之后,ch 上沒有數據到來,那么我們將會進入timeout 分支.
select { case <-ch:// a read from ch has occurred case <-timeout:// the read from ch has timed out }timeout channel 的 buffer 大小為 1, 當 goroutine 發送了 timeout 信號之后,便退出了. goroutine 并不知道它發送的超時信號是否已經被接受,這意味著,如果 在 1秒之內,成功的從 ch 上收到了數據, goroutine 不會因為等待它發送到 timeout channel 上的信號被接受而永遠阻塞.
接下來,我們來看一下這個模式的一種變體. 在這個例子中,我們的程序從多個數據庫中同時讀取數據. 它僅僅需要一個結果,因此它只會接收最先到達的數據.
Query 輸入一個數據庫連接的集合和一個查詢字符串,它會同時查詢這些數據庫,接收第一個查詢結果.
func Query(conns []Conn, query string) Result {ch := make(chan Result)for _, conn := range conns {go func(c Conn) {select {case ch <- c.DoQuery(query):default:}}(conn)}return <-ch }這個方法中,我們為每個數據庫查詢操作開啟一個 goroutine,在 goroutine 中以非阻塞模式返送請求,等待查詢結果. 為每個數據庫連接使用一個單獨 goroutine 確保了一個操作不會影響另一個操作,這些操作并行進行.
END!!!
總結
以上是生活随笔為你收集整理的Go Concurrency Patterns: Timing out, moving on的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 模拟网页行为之工具篇二
- 下一篇: LwIP应用开发笔记之四:LwIP无操作