Commit 489a2632 authored by Rob Pike's avatar Rob Pike

doc: update Concurrency, Functions and Methods, and Control Flow sections

Many parts of the FAQ are dusty and need cleaning up.
This is the first of a series of changes to bring it up to date.
Since it was first written at the time of release, some of the
ideas and background have changed, and some historical
remarks are largely irrelevant now.

Update #26107.

Change-Id: I1f36df7d8ecc8a1a033d5ac4fa1edeece25ed6b4
Reviewed-on: https://go-review.googlesource.com/123496Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent 6f8e8e14
......@@ -1407,16 +1407,28 @@ To find the amount of actual memory allocated to a Go process, use the Unix
What operations are atomic? What about mutexes?</h3>
<p>
We haven't fully defined it all yet, but some details about atomicity are
available in the <a href="/ref/mem">Go Memory Model specification</a>.
A description of the atomicity of operations in Go can be found in
the <a href="/ref/mem">Go Memory Model</a> document.
</p>
<p>
Regarding mutexes, the <a href="/pkg/sync">sync</a>
package implements them, but we hope Go programming style will
encourage people to try higher-level techniques. In particular, consider
structuring your program so that only one goroutine at a time is ever
responsible for a particular piece of data.
Low-level synchronization and atomic primitives are available in the
<a href="/pkg/sync">sync</a> and
<a href="/pkg/sync/atomic">sync/atomic</a>
packages.
These packages are good for simple tasks such as incrementing
reference counts or guaranteeing small-scale mutual exclusion.
</p>
<p>
For higher-level operations, such as coordination among
concurrent servers, higher-level techniques can lead
to nicer programs, and Go supports this approach through
its goroutines and channels.
For instance, you can structure your program so that only one
goroutine at a time is ever responsible for a particular piece of data.
That approach is summarized by the original
<a href="https://www.youtube.com/watch?v=PAAkCSZUG1c">Go proverb</a>,
</p>
<p>
......@@ -1424,7 +1436,13 @@ Do not communicate by sharing memory. Instead, share memory by communicating.
</p>
<p>
See the <a href="/doc/codewalk/sharemem/">Share Memory By Communicating</a> code walk and its <a href="//blog.golang.org/2010/07/share-memory-by-communicating.html">associated article</a> for a detailed discussion of this concept.
See the <a href="/doc/codewalk/sharemem/">Share Memory By Communicating</a> code walk
and its <a href="//blog.golang.org/2010/07/share-memory-by-communicating.html">
associated article</a> for a detailed discussion of this concept.
</p>
<p>
Large concurrent programs are likely to borrow from both these toolkits.
</p>
<h3 id="Why_no_multi_CPU">
......@@ -1432,15 +1450,17 @@ Why doesn't my multi-goroutine program use multiple CPUs?</h3>
<p>
The number of CPUs available simultaneously to executing goroutines is
controlled by the <code>GOMAXPROCS</code> shell environment variable.
In earlier releases of Go, the default value was 1, but as of Go 1.5 the default
value is the number of cores available.
Therefore programs compiled after 1.5 should demonstrate parallel execution
of multiple goroutines.
To change the behavior, set the environment variable or use the similarly-named
controlled by the <code>GOMAXPROCS</code> shell environment variable,
whose default value is the number of CPU cores available.
Programs with the potential for parallel execution should therefore
achieve it by default on a multiple-CPU machine.
To change the number of parallel CPUs to use,
set the environment variable or use the similarly-named
<a href="/pkg/runtime/#GOMAXPROCS">function</a>
of the runtime package to configure the
run-time support to utilize a different number of threads.
Setting it to 1 eliminates the possibility of true parallelism,
forcing independent goroutines to take turns executing.
</p>
<p>
......@@ -1465,10 +1485,10 @@ intrinsically parallel.
<p>
In practical terms, programs that spend more time
communicating on channels than doing computation
synchronizing or communicating than doing useful computation
may experience performance degradation when using
multiple OS threads.
This is because sending data between threads involves switching
This is because passing data between threads involves switching
contexts, which has significant cost.
For instance, the <a href="/ref/spec#An_example_package">prime sieve example</a>
from the Go specification has no significant parallelism although it launches many
......@@ -1542,21 +1562,26 @@ used in flexible ways to interact with it.
Why do T and *T have different method sets?</h3>
<p>
From the <a href="/ref/spec#Types">Go Spec</a>:
As the <a href="/ref/spec#Types">Go specification</a> says,
the method set of a type <code>T</code> consists of all methods
with receiver type <code>T</code>,
while that of the corresponding pointer
type <code>*T</code> consists of all methods with receiver <code>*T</code> or
<code>T</code>.
That means the method set of <code>*T</code>
includes that of <code>T</code>),
but not the reverse.
</p>
<blockquote>
The method set of any other named type <code>T</code> consists of all methods
with receiver type <code>T</code>. The method set of the corresponding pointer
type <code>*T</code> is the set of all methods with receiver <code>*T</code> or
<code>T</code> (that is, it also contains the method set of <code>T</code>).
</blockquote>
<p>
If an interface value contains a pointer <code>*T</code>,
This distinction arises because
if an interface value contains a pointer <code>*T</code>,
a method call can obtain a value by dereferencing the pointer,
but if an interface value contains a value <code>T</code>,
there is no useful way for a method call to obtain a pointer.
there is no safe way for a method call to obtain a pointer.
(Doing so would allow a method to modify the contents of
the value inside the interface, which is not permitted by
the language specification.)
</p>
<p>
......@@ -1654,13 +1679,21 @@ seem odd but works fine in Go:
}
</pre>
<p>
This behavior of the language, not defining a new variable for
each iteration, may have been a mistake in retrospect.
It may be addressed in a later version but, for compatibility,
cannot change in Go version 1.
</p>
<h2 id="Control_flow">Control flow</h2>
<h3 id="Does_Go_have_a_ternary_form">
Does Go have the <code>?:</code> operator?</h3>
Why does Go not have the <code>?:</code> operator?</h3>
<p>
There is no ternary testing operation in Go. You may use the following to achieve the same
There is no ternary testing operation in Go.
You may use the following to achieve the same
result:
</p>
......@@ -1672,6 +1705,14 @@ if expr {
}
</pre>
<p>
The reason <code>?:</code> is absent from Go is that the language's designers
had seen the operation used too often to create impenetrably complex expressions.
The <code>if-else</code> form, although longer,
is unquestionably clearer.
A language needs only one conditional control flow construct.
</p>
<h2 id="Packages_Testing">Packages and Testing</h2>
<h3 id="How_do_I_create_a_multifile_package">
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment