Question

I understand that usually, if I wish to access an out-of-scope variable from a Go routine, it is my responsibility to create a copy to be conceptually owned by the Go routine. Is this also true for channels, or are those exempt?

Effective Go #channels explains this with the words "it may seem odd to write req := req but it's a [sic] legal and idiomatic in Go to do this," referring to this code example:

var sem = make(chan int, MaxOutstanding)
// (other code, filling sem, defining process(..), etc., omitted)

func Serve(queue chan *Request) {
    for req := range queue {
        <-sem
        req := req // Create new instance of req for the goroutine.
        go func() {
            process(req)
            sem <- 1
        }()
    }
}

I happened to have very nearly replicated this example code in my own project (except that I am using a chan struct{} rather than chan int for my semaphore, and declare it local to the Serve func). Staring at it, I am wondering if accessing the same channel from multiple concurrent goroutines is really fine, or if something like sem := sem is called for.

Was it helpful?

Solution 2

Channel accesses are thread-safe, so you do not need to lock it or make local copies of it or anything like that.

OTHER TIPS

Yes, there is no issue with using the same channel from multiple goroutines, it's quite normal to do so.

The reason for the req := req is not for the benefit of the goroutine, but is instead required to prevent unexpected behavior within the closure. Without it, each iteration of the loop will change the value of req within the closure rather than giving it a unique value each time.

A quick example of this effect can be found here: http://play.golang.org/p/ylRQkh2SeC

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top