aboutsummaryrefslogtreecommitdiff
path: root/doc/go_mem.html
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-03-24 19:11:21 -0400
committerRuss Cox <rsc@golang.org>2014-03-24 19:11:21 -0400
commit132e816734de8cb7d5c52ca3a5a707135fc81075 (patch)
tree69465d7625d04787f1bdb5daa8e43e6fa60b8a01 /doc/go_mem.html
parent833dae6d26c56bde5fbae27fde0cdc6efa63fefa (diff)
downloadgo-132e816734de8cb7d5c52ca3a5a707135fc81075.tar.gz
go-132e816734de8cb7d5c52ca3a5a707135fc81075.zip
doc: allow buffered channel as semaphore without initialization
This rule not existing has been the source of many discussions on golang-dev and on issues. We have stated publicly that it is true, but we have never written it down. Write it down. Fixes #6242. LGTM=r, dan.kortschak, iant, dvyukov R=golang-codereviews, r, dominik.honnef, dvyukov, dan.kortschak, iant, 0xjnml CC=golang-codereviews https://golang.org/cl/75130045
Diffstat (limited to 'doc/go_mem.html')
-rw-r--r--doc/go_mem.html35
1 files changed, 35 insertions, 0 deletions
diff --git a/doc/go_mem.html b/doc/go_mem.html
index 3e769daeca..69e7c8ce75 100644
--- a/doc/go_mem.html
+++ b/doc/go_mem.html
@@ -274,6 +274,41 @@ then the program would not be guaranteed to print
crash, or do something else.)
</p>
+<p class="rule">
+The <i>k</i>th send on a channel with capacity <i>C</i> happens before the <i>k</i>+<i>C</i>th receive from that channel completes.
+</p>
+
+<p>
+This rule generalizes the previous rule to buffered channels.
+It allows a counting semaphore to be modeled by a buffered channel:
+the number of items in the channel corresponds to the semaphore count,
+the capacity of the channel corresponds to the semaphore maximum,
+sending an item acquires the semaphore, and receiving an item releases
+the semaphore.
+This is a common idiom for rate-limiting work.
+</p>
+
+<p>
+This program starts a goroutine for every entry in the work list, but the
+goroutines coordinate using the <code>limit</code> channel to ensure
+that at most three are running work functions at a time.
+</p>
+
+<pre>
+var limit = make(chan int, 3)
+
+func main() {
+ for _, w := range work {
+ go func() {
+ limit <- 1
+ w()
+ <-limit
+ }()
+ }
+ select{}
+}
+</pre>
+
<h3>Locks</h3>
<p>