diff options
author | Russ Cox <rsc@golang.org> | 2014-03-24 19:11:21 -0400 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2014-03-24 19:11:21 -0400 |
commit | 132e816734de8cb7d5c52ca3a5a707135fc81075 (patch) | |
tree | 69465d7625d04787f1bdb5daa8e43e6fa60b8a01 /doc/go_mem.html | |
parent | 833dae6d26c56bde5fbae27fde0cdc6efa63fefa (diff) | |
download | go-git-132e816734de8cb7d5c52ca3a5a707135fc81075.tar.gz |
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.html | 35 |
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> |