16 Go Concurrency Patterns: Timing out, moving on GO并发模式: 超时, 继续前进
Go Concurrency Patterns: Timing out, moving on GO并发模式: 超时, 继续前进
23 September 2010
Concurrent programming has its own idioms. A good example is timeouts. Although Go's channels do not support them directly, they are easy to implement. Say we want to receive from the channel ch
, but want to wait at most one second for the value to arrive. We would start by creating a signalling channel and launching a goroutine that sleeps before sending on the channel:
timeout := make(chan bool, 1)
go func() {
time.Sleep(1 * time.Second)
timeout <- true
}()
We can then use a select
statement to receive from either ch
or timeout
. If nothing arrives on ch
after one second, the timeout case is selected and the attempt to read from ch is abandoned.
select {
case <-ch:
// a read from ch has occurred
case <-timeout:
// the read from ch has timed out
}
The timeout
channel is buffered with space for 1 value, allowing the timeout goroutine to send to the channel and then exit. The goroutine doesn't know (or care) whether the value is received. This means the goroutine won't hang around forever if the ch
receive happens before the timeout is reached. The timeout
channel will eventually be deallocated by the garbage collector.
(In this example we used time.Sleep
to demonstrate the mechanics of goroutines and channels. In real programs you should use ` time.After`, a function that returns a channel and sends on that channel after the specified duration.)
Let's look at another variation of this pattern. In this example we have a program that reads from multiple replicated databases simultaneously. The program needs only one of the answers, and it should accept the answer that arrives first.
The function Query
takes a slice of database connections and a query
string. It queries each of the databases in parallel and returns the first response it receives:
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
}
In this example, the closure does a non-blocking send, which it achieves by using the send operation in select
statement with a default
case. If the send cannot go through immediately the default case will be selected. Making the send non-blocking guarantees that none of the goroutines launched in the loop will hang around. However, if the result arrives before the main function has made it to the receive, the send could fail since no one is ready.
This problem is a textbook example of what is known as a race condition, but the fix is trivial. We just make sure to buffer the channel ch
(by adding the buffer length as the second argument to make), guaranteeing that the first send has a place to put the value. This ensures the send will always succeed, and the first value to arrive will be retrieved regardless of the order of execution.
These two examples demonstrate the simplicity with which Go can express complex interactions between goroutines.
By Andrew Gerrand
Related articles
- HTTP/2 Server Push
- Introducing HTTP Tracing
- Generating code
- Go Concurrency Patterns: Context
- Go Concurrency Patterns: Pipelines and cancellation
- Introducing the Go Race Detector
- Advanced Go Concurrency Patterns
- Go maps in action
- go fmt your code
- Concurrency is not parallelism
- Organizing Go code
- Go videos from Google I/O 2012
- Debugging Go programs with the GNU Debugger
- The Go image/draw package
- The Go image package
- The Laws of Reflection
- Error handling and Go
- "First Class Functions in Go"
- Profiling Go Programs
- A GIF decoder: an exercise in Go interfaces
- Introducing Gofix
- Godoc: documenting Go code
- Gobs of data
- C? Go? Cgo!
- JSON and Go
- Go Slices: usage and internals
- Defer, Panic, and Recover
- Share Memory By Communicating
- JSON-RPC: a tale of interfaces
16 Go Concurrency Patterns: Timing out, moving on GO并发模式: 超时, 继续前进的更多相关文章
- Go Concurrency Patterns: Timing out, moving on
https://blog.golang.org/go-concurrency-patterns-timing-out-and
- Go Concurrency Patterns: Pipelines and cancellation
https://blog.golang.org/pipelines Go Concurrency Patterns: Pipelines and cancellation Sameer Ajmani1 ...
- Go Concurrency Patterns: Context At Google, we require that Go programmers pass a Context parameter as the first argument to every function on the call path between incoming and outgoing requests.
小结: 1. Background is the root of any Context tree; it is never canceled: 2. https://blog.golang. ...
- golang语言中的context详解,Go Concurrency Patterns: Context
https://blog.golang.org/context Introduction In Go servers, each incoming request is handled in its ...
- Advanced Go Concurrency Patterns
https://talks.golang.org/2013/advconc.slide#5 It's easy to go, but how to stop? Long-lived programs ...
- 设计模式教程(Design Patterns Tutorial)笔记之三 行为型模式(Behavioral Patterns)
目录 · Strategy · When to use the Strategy Design Pattern? · Sample Code · Observer · When to use the ...
- [Python设计模式] 第16章 上班,干活,下班,加班——状态模式
github地址:https://github.com/cheesezh/python_design_patterns 题目 用代码模拟一天的工作状态,上午状态好,中午想睡觉,下午渐恢复,加班苦煎熬. ...
- 设计模式教程(Design Patterns Tutorial)笔记之一 创建型模式(Creational Patterns)
目录 · 概述 · Factory · What is the Factory Design Pattern? · Sample Code · Abstract Factory · What is t ...
- Ubuntu 16.04/CentOS 6.9安装Apache压力(并发)测试工具ab
说明: ab工具已经在Apache中包含,如果不想安装Apache,那么可以使用下面方法单独安装. 安装: Ubuntu: sudo apt-get install apache2-utils Cen ...
随机推荐
- 【转】查看 Linux 发行版名称和版本号的 8 种方法
如果你加入了一家新公司,要为开发团队安装所需的软件并重启服务,这个时候首先要弄清楚它们运行在什么发行版以及哪个版本的系统上,你才能正确完成后续的工作.作为系统管理员,充分了解系统信息是首要的任务. 查 ...
- Java ConcurrentModificationException 异常分析与解决方案
Java ConcurrentModificationException 异常分析与解决方案http://www.2cto.com/kf/201403/286536.html java.util.Co ...
- fzyjojP2931 乱搞
其实很简单(第二个不知是啥) 贡献独立 其实第一种就是考虑一个点在哈夫曼树上的期望深度是多少 因为精度要求较高 所以要高精小数加,高精小数除以低精整数
- Jenkins(一)---我理解的jenkins是这样的
1.齿轮 如果将 java / maven / ant / git / tomcat / jenkins 等等软件比喻为齿轮:如下图 两个软件在一起可以驱动另外一个软件:如下图 如果把这些软件要集成在 ...
- App统计指标定义
度量(指标) 定义 活跃用户 指启动应用的用户(去重,即1台设备打开多次会被计为1个活跃用户). 是衡量一个应用运营情况最基础的一个指标,用以表示用户规模.通常根据不同的时间限定,有日活跃用户.周活跃 ...
- NATS_03:NATS发布/订阅机制
概念 发布/订阅(Publish/subscribe 或pub/sub)是一种消息范式,消息的发送者(发布者)不是计划发送其消息给特定的接收者(订阅者).而是发布的消息分为不同的类别,而不需要知道什么 ...
- 安装rqalpha的日志
安装rqalpha的日志 用anaconda的控制台命令: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple rqalpha rqalph ...
- [转] malloc基本实现
任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至 ...
- 简单几招,解决jQuery.getJSON的缓存问题
今天做测试工作,发现了一个令我费解的问题,jquery的getJson方法在firefox上运行可以得到返回的结果,但是在ie8上测试,竟发现没有发送请求,故不能取到任何返回的结果,经历了一翻周折,找 ...
- 洛谷P3953 [NOIP2017]逛公园
K<=50,感觉可以DP 先建反图求出从n到各个点的最短路,然后在正图上DP 设f[当前点][比最短路多走的距离]=方案数 转移显然是 $f[v][res]=\sum f[u][res+tmp] ...