This is a creation in Article, where the information may have evolved or changed.
Objective
As a result of the previous phase of the project received in the final, unconsciously many more spare time, so I would like to summarize the recent because of personal interest and learn something. From the beginning of this article and a succession of articles on the Go language, are bloggers recently on the Go language learning process of some sentiment, summary, similar to learning notes. Recorded and organized into a blog for the knowledge of learning to do a collation, two for sharing out to everyone (because the domestic on the go language of Chinese information is relatively small), because Bo master ability and knowledge is limited, inevitably have a mistake, still hope Sheng.
Thanks to the excellent performance of Go, the go has attracted my attention from the very beginning. Like Erlang, Scala and other languages, go is a language that is inherently designed for concurrency, and go has many excellent features that support concurrent programming at the native level, such as the Goroutines, Channels, and select native features. So nonsense, this is a rough summary of the concurrent programming patterns in the Go language, examples from some of the speeches and blogs in Golang conference, and the details of the grammar knowledge involved in the go language will be omitted. Go language syntax please refer to http://golang.org/
Some points of emphasis
1. Concurrency rather than parallelism
First we need to clarify two nouns: concurrency (Concurrency), parallel (Parallelism). These two words may be confusing to everyone because the two-word bids are too similar, but the former is more biased towards design, whereas the latter tends to be more structural (Structure).
If you have only one CPU, then your program can be concurrent, but it must not be parallel
A good concurrency program is not necessarily parallel
Parallelism is a physical state, and concurrency is a design idea, the internal structure of the program
Multiple processors are likely to reach the physical state of concurrency
2. What is Goroutines
Goroutine is a standalone process that executes a function through the GO keyword, which has a separate, self-managed call stack.
Goroutine is very cheap, you can have thousands of or even tens of thousands of goroutines
Goroutine is not thread.
There could be thousands of goroutines under a thread.
You can think of goroutine as a cheap thread.
Let's start with a few examples
Func boring (msg string) {for I: = 0;; i++ {fmt. PRINTLN (msg, i) time. Sleep (time. Second)}}
Obviously, this function never stops printing the MSG string, and the loop will sleep in the middle of a second, and then let's keep improving the function.
Func boring (msg string) {for I: = 0;; i++ {fmt. PRINTLN (msg, i) time. Sleep (time. Duration (Rand. INTN (1E3)) * Time.millisecond)}}
We see that this function is no longer a fixed time for sleep, but Rand has a random duration. In this way, we can make this boring function a little less predictable.
Func main () {boring ("boring!")} Func boring (msg string) {for I: = 0;; i++ {fmt. PRINTLN (msg, i) time. Sleep (time. Duration (Rand. INTN (1E3)) * Time.millisecond)}}
Well, the boring function is running ~ ~ But, at the moment we haven't used the Goroutines feature
Package Mainimport ("FMT" "Math/rand" "Time") Func main () {go boring ("boring!")}
The output of the program is:
[No output] Program exited.
Nani??!! Strange, why does the program not output pinch? The truth is that the main function does not wait for the boring method to call FMT after opening the new goroutine of the boring method. Println in a hurry to return to exit. When main exits, our program naturally exits.
Func main () {go boring ("boring!") Fmt. Println ("I ' m listening.") Time. Sleep (2 * time. Second) fmt. Println ("You ' re boring; I ' m leaving. ")}
Now we can see the message of the boring function output before the main program exits. But wait, we're just a goroutine, not yet involved in the real sense of concurrency.
Let's take a look at a simple example of synchronizing using channels
var syn chan int = make (chan int) func foo () {for (I: = 0; i < 5; i++) {fmt. Println ("I Am running!")} Syn <-1}func main () {go foo () <-syn}
Quite simply, by using the Channel SYN, you can do a simple synchronization. In this way, the main function exits when it is first blocked at the Read Syn, unless Foo writes data to the SYN.
func boring (Msg string, c chan string) { for i := 0; ; i++ { c <- fmt. Sprintf ("%s %d", msg, i) time. Sleep (time. Duration (Rand. INTN (1E3)) * time. Millisecond)}}func main () {c := make (chan string) go boring ("boring!", c) for i := 0; i < 5; i++ { fmt. Printf ("you say: %q\n", <-c) } fmt. Println ("You ' Re boring; i ' m leaving.")}
We connect main and boring through the channel, so that they can communicate naturally without having a relationship, thus knowing each other's state. The above procedure is the synchronization through the channel. Blocking occurs when the main function executes "<-C" unless "C <-FMT" is executed in boring. Sprintf ("%s%d", MSG, i) "writes data to the channel before it is unblocked." From this view, for the same channel,sender and receiver must read a write to make the channel unblocked. This allows communication and synchronization through the channel.