Go Concurrency Patterns: Timing out, moving on
原文地址:https://blog.golang.org/concurrency-timeouts
并發(fā)變成有它自己的風(fēng)格. 一個(gè)非常好的例子就是 timeout. 雖然 go 的 channel 沒(méi)有直接支持 timeout 機(jī)制,但是要實(shí)現(xiàn)它非常容易.
比如說(shuō),我們想從一個(gè) channel ch 中接收數(shù)據(jù),但是最多只想等待 1 秒. 我們可以這么做:創(chuàng)建一個(gè) channel 作為信號(hào) channel (signalling channel), 再創(chuàng)建一個(gè) goroutine,這個(gè) goroutine 再發(fā)送數(shù)據(jù)之前先休眠 1 秒.
timeout := make(chan bool, 1) go func() {time.Sleep(1 * time.Second)timeout <- true }()然后,我們使用 select 語(yǔ)句來(lái)從 ch 上接受數(shù)據(jù). 如果在 1 秒之后,ch 上沒(méi)有數(shù)據(jù)到來(lái),那么我們將會(huì)進(jìn)入timeout 分支.
select { case <-ch:// a read from ch has occurred case <-timeout:// the read from ch has timed out }timeout channel 的 buffer 大小為 1, 當(dāng) goroutine 發(fā)送了 timeout 信號(hào)之后,便退出了. goroutine 并不知道它發(fā)送的超時(shí)信號(hào)是否已經(jīng)被接受,這意味著,如果 在 1秒之內(nèi),成功的從 ch 上收到了數(shù)據(jù), goroutine 不會(huì)因?yàn)榈却l(fā)送到 timeout channel 上的信號(hào)被接受而永遠(yuǎn)阻塞.
接下來(lái),我們來(lái)看一下這個(gè)模式的一種變體. 在這個(gè)例子中,我們的程序從多個(gè)數(shù)據(jù)庫(kù)中同時(shí)讀取數(shù)據(jù). 它僅僅需要一個(gè)結(jié)果,因此它只會(huì)接收最先到達(dá)的數(shù)據(jù).
Query 輸入一個(gè)數(shù)據(jù)庫(kù)連接的集合和一個(gè)查詢字符串,它會(huì)同時(shí)查詢這些數(shù)據(jù)庫(kù),接收第一個(gè)查詢結(jié)果.
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 }這個(gè)方法中,我們?yōu)槊總€(gè)數(shù)據(jù)庫(kù)查詢操作開(kāi)啟一個(gè) goroutine,在 goroutine 中以非阻塞模式返送請(qǐng)求,等待查詢結(jié)果. 為每個(gè)數(shù)據(jù)庫(kù)連接使用一個(gè)單獨(dú) goroutine 確保了一個(gè)操作不會(huì)影響另一個(gè)操作,這些操作并行進(jìn)行.
END!!!
總結(jié)
以上是生活随笔為你收集整理的Go Concurrency Patterns: Timing out, moving on的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 模拟网页行为之工具篇二
- 下一篇: 探索比特币源码3-熟悉RPC接口