From d42a48828f3cff4e57cefaf72bc88cef7d355fd6 Mon Sep 17 00:00:00 2001 From: Kevin Burke Date: Tue, 14 Jun 2022 21:29:36 -0700 Subject: [PATCH] sync: add more notes about Cond behavior Cond is difficult to use correctly (I was just bitten by it in a production app that I inherited). While several proposals have come up to improve or remove sync.Cond, no action has so far been taken. Update the documentation to discourage use of sync.Cond, and point people in the direction of preferred alternatives. I believe this will help encourage behavior we want (less use of sync.Cond and more use of channels), while also paving the way for, potentially, removing Cond in a future version of the language. Thanks very much to Bryan Mills and Sean Liao for discussion and recommendations. Updates #20491. Updates #21165. Change-Id: Ib4d0631c79d4c4d0a30027255cd43bc47cddebd3 Reviewed-on: https://go-review.googlesource.com/c/go/+/412237 Run-TryBot: Ian Lance Taylor Auto-Submit: Ian Lance Taylor Reviewed-by: Bryan Mills TryBot-Result: Gopher Robot Reviewed-by: Ian Lance Taylor --- src/sync/cond.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/sync/cond.go b/src/sync/cond.go index 19f986e4784..cbf5ba60714 100644 --- a/src/sync/cond.go +++ b/src/sync/cond.go @@ -22,6 +22,17 @@ import ( // In the terminology of the Go memory model, Cond arranges that // a call to Broadcast or Signal “synchronizes before” any Wait call // that it unblocks. +// +// For many simple use cases, users will be better off using channels than a +// Cond (Broadcast corresponds to closing a channel, and Signal corresponds to +// sending on a channel). +// +// For more on replacements for sync.Cond, see [Roberto Clapis's series on +// advanced concurrency patterns], as well as [Bryan Mills's talk on concurrency +// patterns]. +// +// [Roberto Clapis's series on advanced concurrency patterns]: https://blogtitle.github.io/categories/concurrency/ +// [Bryan Mills's talk on concurrency patterns]: https://drive.google.com/file/d/1nPdvhB0PutEJzdCq5ms6UI58dp50fcAN/view type Cond struct { noCopy noCopy @@ -64,6 +75,9 @@ func (c *Cond) Wait() { // // It is allowed but not required for the caller to hold c.L // during the call. +// +// Signal() does not affect goroutine scheduling priority; if other goroutines +// are attempting to lock c.L, they may be awoken before a "waiting" goroutine. func (c *Cond) Signal() { c.checker.check() runtime_notifyListNotifyOne(&c.notify)