I am learning about Go's concurrency model and come across an example from the book "Learning Go" - Oreilly. In the below example, "r := <-result" blocks until any Goroutines write to the result channel and because result is unbuffered channel, subsequent writes to result from other Goroutines will block until result channel is empty again. My question is what if there are 2 Goroutines running in parallel and write to the result channel at the same time (result is empty at the time), in that situation, How does the Go runtime resolve the problem?
func searchData(s string, searchers []func(string) []string) []string {
done := make(chan struct{})
result := make(chan []string)
for i, searcher := range searchers {
go func(searcher func(string) []string) {
select {
case result <- searcher(s):
case <-done:
}
}(searcher)
}
r := <-result
close(done)
return r
}
CodePudding user response:
When multiple goroutines write to the same unbuffered channel at the same time, they will both block until another goroutine reads from the channel. When a goroutine reads from the channel, one of the waiting goroutines will proceed with the write and continue while others continue waiting. The writer goroutine will be randomly selected.
This generalizes to multiple readers and multiple writers the same way. If multiple goroutines read from the channel while multiple goroutines are writing to it, a randomly selected goroutine will be able to send a message to another randomly selected goroutine.
CodePudding user response:
You can read the source code of select in go runtime. Go resolve conflict by locking channel.