Golang Channels, Chinese Finger Traps

Paul Yeo
2 min readNov 19, 2020
Chinese Finger Trap
func Google(query string) (results []string) {
c := make(chan string)

go func() {
c <- Web(query)
}()
go func() {
c <- Image(query)
}()
go func() {
c <- Video(query)
}()
timeout := time.After(80 * time.Millisecond)
for i := 0; i < 3; i++ {
select {
case result := <-c:
results = append(results, result)
case <-timeout:
fmt.Println("timed out")
return
}
}
return
}

Let’s take a look at an example from Google I/O talk given by Rob Pike. We see that a channel is used to hold values from various media search queries (Web/Image/Video) that are performed concurrently and returned as a list of strings.

A channel is like a Chinese finger trap. A goroutine (or thread) sends a value to the channel denoted by c <- and another goroutine (usually main) receives the value from the channel <- c. In the code snippet above, we spin up three goroutines to process various media search queries. Each operate independently and finish non-sequentially. When a goroutine finishes, it sends a value from the search to the channel. Channels are mechanism for concurrency, because channels block until there is data to receive, meaning the main goroutine waits until one of the three anonymous literal functions finishes and sends to the channel, which then the main thread receives and appends to the slice.

func Google(query string) (results []string) {
var results []string
var m sync.Mutex
go func() {
m.lock()
results = append(results, Web(query))
m.unlock()
}()
go func() {
m.lock()
results = append(results, Image(query))
m.unlock()
}()
go func() {
m.lock()
results = append(results, Video(query))
m.unlock()
}()
return
}

Above is an alternative using a mutex to lock and unlock the slice before appending to the slice. You can see here that the code shares the memory (mutex and slice) vs channels in Golang. Golang advocates for the idea of not communicating by sharing memory, but passing around values via channels and sharing memory by communicating.

--

--