This is a creation in Article, where the information may have evolved or changed.
Google released the Go programming language in November 2009, designed to be both efficient in C and easy for Python. In March this year, the Go Development Group officially released the first stable release of the Go Language: Go version 1, or go 1. This means that the go language itself and its standard library have stabilized, and developers can now use it as a stable development platform to build their own applications. We use two articles to introduce the features and applications of Go language, this is the second one.
Parallel and Goroutine
However, the development of processor technology indicates that a multiprocessor computer consisting of multiple similar processors (each containing its own storage unit) may be more powerful, reliable, and economical than a single processor that masks a variety of parallel architectures. ---C.A.R Hoare, Turing Award winner, CSP author, 1978
In the the Sixties or seventies of the 20th century, parallel computing was one of the hot spots in order to compensate for processor processing power. There are excellent ideas, such as semaphores (Semaphore), Enhancement (Monitor), lock (mutex), and the synchronization mechanism based on message passing. But in the 80 's, with the rapid improvement of single-core processor performance, academia ushered in the dark period of parallel computing. In the 670 's, only some of the early ideas were used extensively in the actual development. Many of the results of the late 70 were not even being used on a large scale, accompanied with the advent of dark periods of parallel computing, or tepid, or being stored in storage. CSP (Communicating sequential Processes) is one of them. But its elegant and concise approach is still circulating in some small languages. Today, with energy consumption and heat dissipation, processor development is turning to multicore to improve processor performance. Once again we have the parallel computing that we have faced. At this point, the CSP model gradually unfolds its head.
The basic idea of CSP is synchronization and data sharing based on message mechanism. Unlike traditional lock synchronization, the messaging mechanism simplifies program design and can effectively reduce potential bugs. The CSP model-based language has three branches: loyal to the original CSP design, with Occam as the representative of a branch, emphasizing the network and mode, with Erlang as a representative of one; the other is to emphasize the channel of transmitting messages to Squeak,newsqueak,alef, Limbo and go are one of the representatives. It is worth mentioning that, in the third language, most of them are hosted by Rob Pike or involved in the development, which naturally includes go.
Since this branch of Go is characterized by an emphasis on channel, then start with the Go channel. The Go Channel is a data type that goroutine can use to pass data. As for what Goroutine is, it will be discussed in detail later. It is only necessary to interpret it as a run-time structure similar to a thread.
Defines a channel that needs to specify the type of data passed on this channel. It can be a basic data type such as Int,float32,float64, or it can be a user-defined struct, interface, or even the channel itself.
CH: = Make (chan int)
In this way, a channel that passes an integer type is defined. If you want to read a value from this channel, you can use the <-operation. Similarly, the write uses the-I operator:
Read a value from CH to deposit I
I: = <-ch
Writes the value of J to Ch
Ch <-J
The operation of the channel is synchronous, and a read operation executes the following statement only after the content is actually read, while the write operation is executed only after the write data is read by the other end of the channel. (The Go channel can also join the cache queue, not much discussed here)
Also, for channels, the for loop is allowed to process the content from the channel in turn:
Func handle (Queue Chan *request) {for r: = Range Queue { process (R) }}
The task of this function is to continuously read the request struct pointer from the channel and call the process function for processing.
In addition, you can use Select to read and write to multiple channels:
Func Serve (Queue Chan *request, quit Chan bool) {for { Select {case req: = <-queue: process (R)
case <-quit: return } }
This function accepts two channels as a parameter. The first channel queue is used to pass various requests. The second channel, quit, is used to publish a signaling that tells the function to return.
The next thing to say is goroutine. It is a parallel structure that is lighter than threads. When the Go program runs, it is common to run several threads in parallel and then assign the goroutine to each thread. When a goroutine ends or is blocked, another goroutine is dispatched to the thread where the Goroutine is blocked or terminated. Such scheduling ensures that each thread can have a high usage rate and does not have to be in a blocking state all the time. This eliminates the many operating system scheduling threads that result in context switching. According to the official go, it is normal for a go program to run between tens of thousands of and hundreds of thousands of goroutine at the same time.
It is also very simple to use a goroutine, as long as you add a go to the function call:
Go process (r)
In this way, the process function is run in a single goroutine.
As a result, the server-side processing of concurrent connections is greatly simplified. It is well known that if a thread is to handle only one user connection, it will be very simple to develop, but not efficient, and if a thread handles multiple user connections, it makes development more difficult. The use of Goroutine with the channel will not increase the difficulty of development, but also improve the efficiency.
Consider a scenario in which the server receives client requests from the network, does some processing, and returns the results to the customer.
For different user connections, use a different goroutine processing. Defines a struct named Userconn to represent a user connection. At the same time, the struct defines a method called Readrequest, which reads the user's request from the network, and a method called Writeresponse, which is used to pass results to the user from the network. As an example of imagination, specific implementation details are not detailed here.
So, for each connection, the thing to do is about this:
Func serveclient (conn *userconn) { ch: = Make (chan *response) //Create a goroutine, //dedicated to send results to users go Writeres (conn, ch) for {// read a request, // judgment type //If the user request is closed, // the function returns req: = conn. Readrequest () switch req. Type {case normal_request: go process (req, ch) case EXIT: return }} }
The basic structure of writeres and process is approximately as follows:
Func writeres (conn *userconn, Ch Chan *response) {for r: = Range CH { Conn. Writeresponse (R) }}
Func process (req *request, ch Chan *response) { Res: = Calculate (req) ch <-res}
The channel itself is very much in line with people's intuitive definition of communication tools, and developers can naturally use channels to establish relationships between goroutine. With channels and goroutine, the tasks to be accomplished by each function are single, reducing the likelihood of errors. In code, the memory space is shared by passing pointers, which are synchronized with the message before each share. This is another go principle: to share memory by passing messages, instead of using shared memory to deliver messages. This simplifies the development of parallel programs.
As a practical programming language, go does not provide a channel-only way to synchronize, as the original CSP paper says. Go in the standard library also provides a tool based on traditional synchronization mechanisms such as locks and semaphores. In the above code, there is actually a potential bug:serveclient function that does not exit after the execution of all the goroutine that run the process, but exits immediately after the exit command from the client is received. A more reasonable operation should be returned after all the goroutine that processed the connection have exited. In the standard library, there is a waitgroup structure that can specifically address the problem of waiting for multiple goroutine. Not detailed here.
The next step is to open a goroutine for each user connection and execute the Serveclient function. As mentioned earlier, because Goroutine is a lighter-weight dispatch unit than threads, this number of goroutine does not result in a significant performance degradation.
Because Goroutine and messaging mechanisms simplify development, and go encourages such designs, developers consciously choose to design based on multiple goroutine. Another benefit of this is the extensibility of the program on multicore systems. As the number of processor cores increases, how to discover the parallel structure inherent in the program is a big challenge for current developers. With go writing, multiple goroutine-based designs tend to have enough parallel structures to scale to multicore processors. Each goroutine can actually be placed on a separate processor and executed in parallel with the other goroutine. That is, the code written for the four-core processor today may not have to be modified to run on the CPU of the next 128 cores and use all the cores at the same time.
No configuration required, direct compilation
if go needs a configuration file that describes how to compile and build the Go-write program, that's the failure of Go. ---Go official documentation
For tools such as Make,autoconf,automake, which specify compilation order and dependencies, go's attitude is that when developers write code, they leave enough information about dependencies and should not require developers to write a separate configuration file to indicate dependencies and compilation order. To do this, developers only need to configure the good one directory structure and an environment variable after installing the Go toolchain, according to the official documentation. Any subsequent installation of the Go program, compiling any GO Program/library requires just a few simple commands.
For a program that is self-contained (not dependent on any third party libraries), simply running go build in the current directory compiles the entire program.
What if my program relies on a third-party library? Very simply, in the import statement in the code, write the location of the third-party library in the network. The import here is the same as the import concept in Java/python, which introduces a package.
Import ( "FMT" "Github.com/monnand/goredis")
The first package introduced in import is the FMT, which is a package in the standard library that provides formatted input and output of the printf class. The second package introduced is the code base on GitHub. It will be introduced on GitHub, under User Monnand, Goredis the package defined by this project.
Next, call the GO command to install the library:
Go get Github.com/monnand/goredis
In this way, the Go program automatically downloads, compiles, and installs the library (including its dependencies). Then use go build to compile the dependent Goredis program.
In addition, if the dependent Goredis program is also in GitHub (or other go-supported version control libraries), it is sufficient to use only one go get command to indicate the remote address where the program is located, and go will download and install various dependencies on its own. In addition to Github,go support Google Code,bitbucket,launchpad, or any other server, use Svn,git,bazzar,mercurial to do version control of Go program/library. All of this greatly simplifies the operations of developers and end users.
Talk about running efficiency again
Matt: How much more efficient is the JSON API node compared to the (original) Sinatra/ruby scheme after using Pat/go? Give an estimate, you can.
Blake: About 10,000 times
Matt: Pretty! Can I quote you?
Blake: I'll check again, I feel like I underestimated it.
---Matt Aimonetti's dialogue with Blake Mizerany on Twitter.
The running efficiency of Go program has been the focus of people's attention. On the one hand, go syntax, type system is very simple, for the development and optimization of the compiler provides a lot of space. On the other hand, go as a statically compiled language, the code is compiled directly into machine code, without intermediate interpretation.
However, if you search the Internet, you will find that the GO program operating efficiency, there is a serious polarization. Part of the test shows that the go program is very efficient, even more than the equivalent program written in C + +. Another part of the test is realistic, and in some ways, go is not even as stackless as the Python-written script.
The go compiler itself still has a lot of space for optimization, but the resulting machine code efficiency is relatively high. The standard library-which includes various runtime code, such as garbage collection, hash tables, and so on-has not been optimized yet, and some are still in a very rudimentary phase. This is one of the reasons why there are serious differences in test results on the network. In addition, as a new language, developers are unfamiliar with it, writing code may have performance bottlenecks, but also increased the results of the evaluation of differences.
One of the developers of the go language, Russ Cox, has published an article on the official Go blog. It uses the code of a benchmark program (Benchmark) to optimize the C + + test and go test sections respectively. Optimized go program run time, even just optimized C + + program run time of 65.8%! This also reflects the potential of go from one side.
There are still many flaws in the Go language: garbage collection is still in a relatively rudimentary stage, and support for 32-bit systems is not perfect, and some standard library code needs to be optimized. According to go official, the future will use a completely parallel garbage collector, which will greatly improve performance. With the release of Go 1, the Go development team will also shift effort from the syntax and standard library specifications to the optimizations of compilers and standard libraries. Go program efficiency, the target will be the approximation of C + +, beyond Java.
Summarize
for now, I think it's a lot better than C + + for system-level development. Use it to develop more efficiently and to solve many problems in a simpler way than C + +. ----Bruce Eckel, author of "C + + programming thought" Java Programming thought
UNIX founder Ken Thonpson;unix/plan 9 developer Rob Pike,russ cox;memcached author Brad Fitzpatrick;java hotspot compiler author one of the Chrome One of V8 engine authors Robert Griesemer;gold Connector author, gcc community active developer Ian Lancetaylor ... When such a group of people together, no matter what development, the team itself may be enough to attract the attention of the crowd. And go as such a team to develop the language, so far has brought a lot of people surprise.
There are already many companies using go to develop production-level programs. Rob Pike has revealed that Google is gradually starting to use go. YouTube uses go to write core parts, and it organizes some of the code into open source project vitess. Domestic including watercress, qbox and other companies have been the first step into the field of Go language.
With the launch of Go 1, a stable go language platform and open source community have been formed. For developers who like to try out new languages, go is a choice.
=====================================
Welcome to follow the code, learn golang! together