OLD | NEW |
1 <!--{ | 1 <!--{ |
2 "Title": "The Go Memory Model", | 2 "Title": "The Go Memory Model", |
3 "Subtitle": "Version of March 6, 2012", | 3 "Subtitle": "Version of March 6, 2012", |
4 "Path": "/ref/mem" | 4 "Path": "/ref/mem" |
5 }--> | 5 }--> |
6 | 6 |
7 <style> | 7 <style> |
8 p.rule { | 8 p.rule { |
9 font-style: italic; | 9 font-style: italic; |
10 } | 10 } |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 before the <code>print</code>. | 267 before the <code>print</code>. |
268 </p> | 268 </p> |
269 | 269 |
270 <p> | 270 <p> |
271 If the channel were buffered (e.g., <code>c = make(chan int, 1)</code>) | 271 If the channel were buffered (e.g., <code>c = make(chan int, 1)</code>) |
272 then the program would not be guaranteed to print | 272 then the program would not be guaranteed to print |
273 <code>"hello, world"</code>. (It might print the empty string, | 273 <code>"hello, world"</code>. (It might print the empty string, |
274 crash, or do something else.) | 274 crash, or do something else.) |
275 </p> | 275 </p> |
276 | 276 |
| 277 <p class="rule"> |
| 278 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. |
| 279 </p> |
| 280 |
| 281 <p> |
| 282 This rule generalizes the previous rule to buffered channels. |
| 283 It allows a counting semaphore to be modeled by a buffered channel: |
| 284 the number of items in the channel corresponds to the semaphore count, |
| 285 the capacity of the channel corresponds to the semaphore maximum, |
| 286 sending an item acquires the semaphore, and receiving an item releases |
| 287 the semaphore. |
| 288 This is a common idiom for rate-limiting work. |
| 289 </p> |
| 290 |
| 291 <p> |
| 292 This program starts a goroutine for every entry in the work list, but the |
| 293 goroutines coordinate using the <code>limit</code> channel to ensure |
| 294 that at most three are running work functions at a time. |
| 295 </p> |
| 296 |
| 297 <pre> |
| 298 var limit = make(chan int, 3) |
| 299 |
| 300 func main() { |
| 301 for _, w := range work { |
| 302 go func() { |
| 303 limit <- 1 |
| 304 w() |
| 305 <-limit |
| 306 }() |
| 307 } |
| 308 select{} |
| 309 } |
| 310 </pre> |
| 311 |
277 <h3>Locks</h3> | 312 <h3>Locks</h3> |
278 | 313 |
279 <p> | 314 <p> |
280 The <code>sync</code> package implements two lock data types, | 315 The <code>sync</code> package implements two lock data types, |
281 <code>sync.Mutex</code> and <code>sync.RWMutex</code>. | 316 <code>sync.Mutex</code> and <code>sync.RWMutex</code>. |
282 </p> | 317 </p> |
283 | 318 |
284 <p class="rule"> | 319 <p class="rule"> |
285 For any <code>sync.Mutex</code> or <code>sync.RWMutex</code> variable <code>l</c
ode> and <i>n</i> < <i>m</i>, | 320 For any <code>sync.Mutex</code> or <code>sync.RWMutex</code> variable <code>l</c
ode> and <i>n</i> < <i>m</i>, |
286 call <i>n</i> of <code>l.Unlock()</code> happens before call <i>m</i> of <code>l
.Lock()</code> returns. | 321 call <i>n</i> of <code>l.Unlock()</code> happens before call <i>m</i> of <code>l
.Lock()</code> returns. |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 <p> | 534 <p> |
500 Even if <code>main</code> observes <code>g != nil</code> and exits its loop, | 535 Even if <code>main</code> observes <code>g != nil</code> and exits its loop, |
501 there is no guarantee that it will observe the initialized | 536 there is no guarantee that it will observe the initialized |
502 value for <code>g.msg</code>. | 537 value for <code>g.msg</code>. |
503 </p> | 538 </p> |
504 | 539 |
505 <p> | 540 <p> |
506 In all these examples, the solution is the same: | 541 In all these examples, the solution is the same: |
507 use explicit synchronization. | 542 use explicit synchronization. |
508 </p> | 543 </p> |
OLD | NEW |