My specific issue is that I have an unbuffered channel and am spawning multiple goroutines bounded with a semaphore to perform work:
func main() {
sem := make(chan struct{}, 10) // allow ten concurrent parsers
wg := &sync.WaitGroup{}
wg.Add(1)
DoSomething("http://example.com", sem, wg)
wg.Wait()
// all done
}
func DoSomething(u string, sem chan struct{}, wg *sync.WaitGroup) {
defer wg.Done()
sem <- struct{}{} // grab
defer func() { <-sem }() // release
var newSomethings []string
// ...
for u := range newSomethings {
wg.Add(1)
go DoSomething(u)
}
}
If there are multiple DoSomething
goroutines on the stack, blocked on the sem
write (or inversely on a read) When a write happens is there any ordering to which go routine gets through with the write?? I would guess it were random but I could imagine:
- it is random
- writes/receives happen in the order they are registered
- implementation dependent
I looked at a couple of resources and was unable to find a solution:
- https://github.com/golang/go/issues/247
- https://golang.org/ref/spec#Receive_operator
- https://golang.org/ref/spec#Channel_types
I'm wondering if this is undefined and/or implementation dependent, or if this logic is located and defined somewhere within go core?