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 selectstatement 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 ...
随机推荐
- uoj259 & 独立集问题的一些做法
很早以前就做了一遍这题,当时好像啥都不会,今天重做一下. 这个题题意简单地说就是输入k.p和一个图,求图大小为k的独立集个数mod p. subset1.in n=24,m=19,k=8 subse ...
- png?wxfrom=5&wx_lazy=1
作为一名游戏行业的视频&平面设计师,平时的工作就是为公司发行的游戏制作宣传视频.广告.平面宣传图,打交道最多的自然就是Adobe家族的设计软件,Photoshop.AfterEffects.P ...
- BZOJ 3787: Gty的文艺妹子序列
3787: Gty的文艺妹子序列 Time Limit: 50 Sec Memory Limit: 256 MBSubmit: 186 Solved: 58[Submit][Status][Dis ...
- Timus 1005 解题报告
题目链接 http://acm.timus.ru/problem.aspx?space=1&num=1005 题目大意 给你一堆石头,现在需要你将这堆石头分成两堆,要求两堆石头的重量相差最小, ...
- 【线段树】【CF1083C】 Max Mex
Description 给定一棵有 \(n\) 个点的树,每个节点有点权.所有的点权构成了一个 \(0~\sim~n - 1\) 的排列.有 \(q\) 次操作,每次操作 \(1\) 为交换两个点的点 ...
- 3:JavaBean,EJB,POJO
JavaBeanJavaBean是公共Java类,但是为了编辑工具识别,需要满足至少三个条件: 有一个public默认构造器(例如无参构造器,) 属性使用public 的get,set方法访问,也就是 ...
- k-Nearest Neighbor algorithm 思想
转载 KNN--K最邻近算法思想 KNN算法的决策过程 k-Nearest Neighbor algorithm 上图中,绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?如果K=3, ...
- c动态分配结构体二维数组
这个问题我纠结了蛮久了,因为前面一直忙(自己也懒了点),所以没有能好好研究这个.希望这篇文章能够帮助你们. #include <stdio.h> #include <stdlib.h ...
- python的匿名函数 lambda的使用方法详解以及使用案例
1.匿名函数是用lambda这个关键字定义 lambda x:x+1 第一个x代表形参,x+1相当于函数的返回值 #lambda x:x+1 第一个x代表形参,x+1相当于函数的返回值 def ...
- Windows Server2008 R2中的角色
AD Certificate Services 官方说明: Active Directory 证书服务 (AD CS) 提供可自定义的服务,用于颁发和管理使用公钥技术的软件安全系统中的证书.可以使用 ...