From 4e5296d4ba82a5f547d4519e88147adcbbaa2953 Mon Sep 17 00:00:00 2001
From: Rob Pike a = 1; b = 2;
, a second goroutine might observe
+executes a = 1; b = 2;
, another might observe
the updated value of b
before the updated value of a
.
-To specify the requirements on reads and writes, we define
+To specify the requirements of reads and writes, we define
happens before, a partial order on the execution
of memory operations in a Go program. If event e1 happens
before event e2, then we say that e2 happens after e1.
@@ -34,7 +35,7 @@ after e2, then we say that
-For example, this program:
+This program:
-is also guaranteed to print "hello, world". The write to
-For example, this program:
+This program:
-var c = make(chan int);
-var a string;
+var c = make(chan int)
+var a string
func f() {
a = "hello, world";
@@ -211,7 +212,7 @@ func main() {
a
+is also guaranteed to print "hello, world"
. The write to a
happens before the receive on c
, which happens before
the corresponding send on c
completes, which happens
before the print
.
@@ -237,12 +238,12 @@ the n'th call to l.Unlock()
happens before the m'th c
-var l sync.Mutex;
-var a string;
+var l sync.Mutex
+var a string
func f() {
a = "hello, world";
@@ -278,16 +279,16 @@ but only one will run
f()
, and the other calls block
until f()
has returned.
-A single call to f()
happens before once.Do(f)
returns.
+
+A single call of f()
from once.Do(f)
happens (returns) before any call of once.Do(f)
returns.
-For example, in this program: +In this program:
-var a string; +var a string func setup() { a = "hello, world"; @@ -319,11 +320,11 @@ will observe writes that happened before w.-For example, in this program: +In this program:
-var a, b int; +var a, b int func f() { a = 1; @@ -346,18 +347,18 @@ it can happen thatg
prints2
and then0
.-This fact invalidates a few obvious idioms. +This fact invalidates a few common idioms.
Double-checked locking is an attempt to avoid the overhead of synchronization. -For example, the
twoprint
program above, might be +For example, thetwoprint
program might be incorrectly written as:-var a string; -var done bool; +var a string +var done bool func setup() { a = "hello, world"; @@ -389,8 +390,8 @@ Another incorrect idiom is busy waiting for a value, as in:-var a string; -var done bool; +var a string +var done bool func setup() { a = "hello, world"; @@ -407,7 +408,7 @@ func main() {As before, there is no guarantee that, in
main
, -observing of the write todone
+observing the write todone
implies observing the write toa
, so this program could print an empty string too. Worse, there is no guarantee that the write todone
will ever @@ -417,7 +418,7 @@ guaranteed to finish.-There are subtler variants on this theme. For example, in this program: +There are subtler variants on this theme, such as this program.
@@ -425,7 +426,7 @@ type T struct { msg string; } -var g *T; +var g *T func setup() { t := new(T); @@ -451,16 +452,3 @@ value forg.msg
. In all these examples, the solution is the same: use explicit synchronization. - - - - - - -