Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(901)

Side by Side Diff: doc/go_mem.html

Issue 893041: code review 893041: Update doc/go_mem.html to remove semicolons. (Closed)
Patch Set: code review 893041: Update doc/go_mem.html to remove semicolons. Created 14 years, 12 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 <!-- The Go Memory Model --> 1 <!-- The Go Memory Model -->
2 2
3 <h2>Introduction</h2> 3 <h2>Introduction</h2>
4 4
5 <p> 5 <p>
6 The Go memory model specifies the conditions under which 6 The Go memory model specifies the conditions under which
7 reads of a variable in one goroutine can be guaranteed to 7 reads of a variable in one goroutine can be guaranteed to
8 observe values produced by writes to the same variable in a different goroutine. 8 observe values produced by writes to the same variable in a different goroutine.
9 </p> 9 </p>
10 10
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 <p class="rule"> 119 <p class="rule">
120 The <code>go</code> statement that starts a new goroutine 120 The <code>go</code> statement that starts a new goroutine
121 happens before the goroutine's execution begins. 121 happens before the goroutine's execution begins.
122 </p> 122 </p>
123 123
124 <p> 124 <p>
125 For example, in this program: 125 For example, in this program:
126 </p> 126 </p>
127 127
128 <pre> 128 <pre>
129 var a string; 129 var a string
130 130
131 func f() { 131 func f() {
132 » print(a); 132 » print(a)
133 } 133 }
134 134
135 func hello() { 135 func hello() {
136 » a = "hello, world"; 136 » a = "hello, world"
137 » go f(); 137 » go f()
138 } 138 }
139 </pre> 139 </pre>
140 140
141 <p> 141 <p>
142 calling <code>hello</code> will print <code>"hello, world"</code> 142 calling <code>hello</code> will print <code>"hello, world"</code>
143 at some point in the future (perhaps after <code>hello</code> has returned). 143 at some point in the future (perhaps after <code>hello</code> has returned).
144 </p> 144 </p>
145 145
146 <h3>Channel communication</h3> 146 <h3>Channel communication</h3>
147 147
(...skipping 11 matching lines...) Expand all
159 159
160 <p> 160 <p>
161 This program: 161 This program:
162 </p> 162 </p>
163 163
164 <pre> 164 <pre>
165 var c = make(chan int, 10) 165 var c = make(chan int, 10)
166 var a string 166 var a string
167 167
168 func f() { 168 func f() {
169 » a = "hello, world"; 169 » a = "hello, world"
170 » c &lt;- 0; 170 » c &lt;- 0
171 } 171 }
172 172
173 func main() { 173 func main() {
174 » go f(); 174 » go f()
175 » &lt;-c; 175 » &lt;-c
176 » print(a); 176 » print(a)
177 } 177 }
178 </pre> 178 </pre>
179 179
180 <p> 180 <p>
181 is guaranteed to print <code>"hello, world"</code>. The write to <code>a</code> 181 is guaranteed to print <code>"hello, world"</code>. The write to <code>a</code>
182 happens before the send on <code>c</code>, which happens before 182 happens before the send on <code>c</code>, which happens before
183 the corresponding receive on <code>c</code> completes, which happens before 183 the corresponding receive on <code>c</code> completes, which happens before
184 the <code>print</code>. 184 the <code>print</code>.
185 </p> 185 </p>
186 186
187 <p class="rule"> 187 <p class="rule">
188 A receive from an unbuffered channel happens before 188 A receive from an unbuffered channel happens before
189 the send on that channel completes. 189 the send on that channel completes.
190 </p> 190 </p>
191 191
192 <p> 192 <p>
193 This program (as above, but with the send and receive statements swapped and 193 This program (as above, but with the send and receive statements swapped and
194 using an unbuffered channel): 194 using an unbuffered channel):
195 </p> 195 </p>
196 196
197 <pre> 197 <pre>
198 var c = make(chan int) 198 var c = make(chan int)
199 var a string 199 var a string
200 200
201 func f() { 201 func f() {
202 » a = "hello, world"; 202 » a = "hello, world"
203 » &lt;-c; 203 » &lt;-c
204 } 204 }
205 </pre> 205 </pre>
206 206
207 <pre> 207 <pre>
208 func main() { 208 func main() {
209 » go f(); 209 » go f()
210 » c &lt;- 0; 210 » c &lt;- 0
211 » print(a); 211 » print(a)
212 } 212 }
213 </pre> 213 </pre>
214 214
215 <p> 215 <p>
216 is also guaranteed to print <code>"hello, world"</code>. The write to <code>a</ code> 216 is also guaranteed to print <code>"hello, world"</code>. The write to <code>a</ code>
217 happens before the receive on <code>c</code>, which happens before 217 happens before the receive on <code>c</code>, which happens before
218 the corresponding send on <code>c</code> completes, which happens 218 the corresponding send on <code>c</code> completes, which happens
219 before the <code>print</code>. 219 before the <code>print</code>.
220 </p> 220 </p>
221 221
(...skipping 18 matching lines...) Expand all
240 240
241 <p> 241 <p>
242 This program: 242 This program:
243 </p> 243 </p>
244 244
245 <pre> 245 <pre>
246 var l sync.Mutex 246 var l sync.Mutex
247 var a string 247 var a string
248 248
249 func f() { 249 func f() {
250 » a = "hello, world"; 250 » a = "hello, world"
251 » l.Unlock(); 251 » l.Unlock()
252 } 252 }
253 253
254 func main() { 254 func main() {
255 » l.Lock(); 255 » l.Lock()
256 » go f(); 256 » go f()
257 » l.Lock(); 257 » l.Lock()
258 » print(a); 258 » print(a)
259 } 259 }
260 </pre> 260 </pre>
261 261
262 <p> 262 <p>
263 is guaranteed to print <code>"hello, world"</code>. 263 is guaranteed to print <code>"hello, world"</code>.
264 The first call to <code>l.Unlock()</code> (in <code>f</code>) happens 264 The first call to <code>l.Unlock()</code> (in <code>f</code>) happens
265 before the second call to <code>l.Lock()</code> (in <code>main</code>) returns, 265 before the second call to <code>l.Lock()</code> (in <code>main</code>) returns,
266 which happens before the <code>print</code>. 266 which happens before the <code>print</code>.
267 </p> 267 </p>
268 268
(...skipping 19 matching lines...) Expand all
288 </p> 288 </p>
289 289
290 <p> 290 <p>
291 In this program: 291 In this program:
292 </p> 292 </p>
293 293
294 <pre> 294 <pre>
295 var a string 295 var a string
296 296
297 func setup() { 297 func setup() {
298 » a = "hello, world"; 298 » a = "hello, world"
299 } 299 }
300 300
301 func doprint() { 301 func doprint() {
302 » once.Do(setup); 302 » once.Do(setup)
303 » print(a); 303 » print(a)
304 } 304 }
305 305
306 func twoprint() { 306 func twoprint() {
307 » go doprint(); 307 » go doprint()
308 » go doprint(); 308 » go doprint()
309 } 309 }
310 </pre> 310 </pre>
311 311
312 <p> 312 <p>
313 calling <code>twoprint</code> causes <code>"hello, world"</code> to be printed t wice. 313 calling <code>twoprint</code> causes <code>"hello, world"</code> to be printed t wice.
314 The first call to <code>twoprint</code> runs <code>setup</code> once. 314 The first call to <code>twoprint</code> runs <code>setup</code> once.
315 </p> 315 </p>
316 316
317 <h2>Incorrect synchronization</h2> 317 <h2>Incorrect synchronization</h2>
318 318
319 <p> 319 <p>
320 Note that a read <span class="event">r</span> may observe the value written by a write <span class="event">w</span> 320 Note that a read <span class="event">r</span> may observe the value written by a write <span class="event">w</span>
321 that happens concurrently with <span class="event">r</span>. 321 that happens concurrently with <span class="event">r</span>.
322 Even if this occurs, it does not imply that reads happening after <span class="e vent">r</span> 322 Even if this occurs, it does not imply that reads happening after <span class="e vent">r</span>
323 will observe writes that happened before <span class="event">w</span>. 323 will observe writes that happened before <span class="event">w</span>.
324 </p> 324 </p>
325 325
326 <p> 326 <p>
327 In this program: 327 In this program:
328 </p> 328 </p>
329 329
330 <pre> 330 <pre>
331 var a, b int 331 var a, b int
332 332
333 func f() { 333 func f() {
334 » a = 1; 334 » a = 1
335 » b = 2; 335 » b = 2
336 } 336 }
337 337
338 func g() { 338 func g() {
339 » print(b); 339 » print(b)
340 » print(a); 340 » print(a)
341 } 341 }
342 342
343 func main() { 343 func main() {
344 » go f(); 344 » go f()
345 » g(); 345 » g()
346 } 346 }
347 </pre> 347 </pre>
348 348
349 <p> 349 <p>
350 it can happen that <code>g</code> prints <code>2</code> and then <code>0</code>. 350 it can happen that <code>g</code> prints <code>2</code> and then <code>0</code>.
351 </p> 351 </p>
352 352
353 <p> 353 <p>
354 This fact invalidates a few common idioms. 354 This fact invalidates a few common idioms.
355 </p> 355 </p>
356 356
357 <p> 357 <p>
358 Double-checked locking is an attempt to avoid the overhead of synchronization. 358 Double-checked locking is an attempt to avoid the overhead of synchronization.
359 For example, the <code>twoprint</code> program might be 359 For example, the <code>twoprint</code> program might be
360 incorrectly written as: 360 incorrectly written as:
361 </p> 361 </p>
362 362
363 <pre> 363 <pre>
364 var a string 364 var a string
365 var done bool 365 var done bool
366 366
367 func setup() { 367 func setup() {
368 » a = "hello, world"; 368 » a = "hello, world"
369 » done = true; 369 » done = true
370 } 370 }
371 371
372 func doprint() { 372 func doprint() {
373 if !done { 373 if !done {
374 » » once.Do(setup); 374 » » once.Do(setup)
375 } 375 }
376 » print(a); 376 » print(a)
377 } 377 }
378 378
379 func twoprint() { 379 func twoprint() {
380 » go doprint(); 380 » go doprint()
381 » go doprint(); 381 » go doprint()
382 } 382 }
383 </pre> 383 </pre>
384 384
385 <p> 385 <p>
386 but there is no guarantee that, in <code>doprint</code>, observing the write to <code>done</code> 386 but there is no guarantee that, in <code>doprint</code>, observing the write to <code>done</code>
387 implies observing the write to <code>a</code>. This 387 implies observing the write to <code>a</code>. This
388 version can (incorrectly) print an empty string 388 version can (incorrectly) print an empty string
389 instead of <code>"hello, world"</code>. 389 instead of <code>"hello, world"</code>.
390 </p> 390 </p>
391 391
392 <p> 392 <p>
393 Another incorrect idiom is busy waiting for a value, as in: 393 Another incorrect idiom is busy waiting for a value, as in:
394 </p> 394 </p>
395 395
396 <pre> 396 <pre>
397 var a string 397 var a string
398 var done bool 398 var done bool
399 399
400 func setup() { 400 func setup() {
401 » a = "hello, world"; 401 » a = "hello, world"
402 » done = true; 402 » done = true
403 } 403 }
404 404
405 func main() { 405 func main() {
406 » go setup(); 406 » go setup()
407 for !done { 407 for !done {
408 } 408 }
409 » print(a); 409 » print(a)
410 } 410 }
411 </pre> 411 </pre>
412 412
413 <p> 413 <p>
414 As before, there is no guarantee that, in <code>main</code>, 414 As before, there is no guarantee that, in <code>main</code>,
415 observing the write to <code>done</code> 415 observing the write to <code>done</code>
416 implies observing the write to <code>a</code>, so this program could 416 implies observing the write to <code>a</code>, so this program could
417 print an empty string too. 417 print an empty string too.
418 Worse, there is no guarantee that the write to <code>done</code> will ever 418 Worse, there is no guarantee that the write to <code>done</code> will ever
419 be observed by <code>main</code>, since there are no synchronization 419 be observed by <code>main</code>, since there are no synchronization
420 events between the two threads. The loop in <code>main</code> is not 420 events between the two threads. The loop in <code>main</code> is not
421 guaranteed to finish. 421 guaranteed to finish.
422 </p> 422 </p>
423 423
424 <p> 424 <p>
425 There are subtler variants on this theme, such as this program. 425 There are subtler variants on this theme, such as this program.
426 </p> 426 </p>
427 427
428 <pre> 428 <pre>
429 type T struct { 429 type T struct {
430 » msg string; 430 » msg string
431 } 431 }
432 432
433 var g *T 433 var g *T
434 434
435 func setup() { 435 func setup() {
436 » t := new(T); 436 » t := new(T)
437 » t.msg = "hello, world"; 437 » t.msg = "hello, world"
438 » g = t; 438 » g = t
439 } 439 }
440 440
441 func main() { 441 func main() {
442 » go setup(); 442 » go setup()
443 for g == nil { 443 for g == nil {
444 } 444 }
445 » print(g.msg); 445 » print(g.msg)
446 } 446 }
447 </pre> 447 </pre>
448 448
449 <p> 449 <p>
450 Even if <code>main</code> observes <code>g != nil</code> and exits its loop, 450 Even if <code>main</code> observes <code>g != nil</code> and exits its loop,
451 there is no guarantee that it will observe the initialized 451 there is no guarantee that it will observe the initialized
452 value for <code>g.msg</code>. 452 value for <code>g.msg</code>.
453 </p> 453 </p>
454 454
455 <p> 455 <p>
456 In all these examples, the solution is the same: 456 In all these examples, the solution is the same:
457 use explicit synchronization. 457 use explicit synchronization.
458 </p> 458 </p>
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b