Go language Troika-Tencent Cloud community

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Introductory Remarks: Three core designs of the Go language: interface, Goroutine, channel

Less is More--wikipedia

Interface

Go is an interface-oriented programming language, and the design of interface is a natural priority. The clever thing about interface design in Go is that the empty interface can be used as a "Duck" type, which makes static languages such as go a certain dynamic, without losing the advantage of a static language's compile-time checks on type safety.

Source code

From the bottom-up implementation, interface is actually a struct with two members. One of the member pointers points to the area containing the type information, which can be understood as a virtual table pointer, while the other points to the specific data, which is the data that the interface actually references.

Where InterfaceType contains some information about the interface itself, _type represents the specific implementation type, described in detail in eface below, bad is a state variable, fun is a pointer array of length 1, in fun[0] The corresponding function pointer of the method is saved in turn. Go runtime package has a hash table, through this hash table can be obtained itab,link and Inhash is to save the hash table in the corresponding location and set the identity. The main code is as follows:

The structure of the ITAB is as follows:

Where InterfaceType contains some information about the interface itself, _type represents the specific implementation type, described in detail in eface below, bad is a state variable, fun is a pointer array of length 1, in fun[0] The corresponding function pointer of the method is saved in turn. Go runtime package has a hash table, through this hash table can be obtained itab,link and Inhash is to save the hash table in the corresponding location and set the identity. The main code is as follows:

The implementation of the Null interface is slightly different. Any object in go can be represented as interface{}, similar to void* in C, and type information is stored in interface{}.

The structure of type is as follows:

I_example

For the application of interface , here is a simple example of how go interacts with the MySQL database.

First create a Task information table in the MySQL test library:

Database interaction the most basic four operations: additions and deletions, here to query for example:

Go to query all the data in this table

which

This code can implement the simple logic of table lookup, but there is a small problem is that our table structure is relatively simple only 4 fields, if you change a 20+ field or even more tables to query, this code seems too inefficient, this time we can introduce interface{} To optimize.
The optimized code is as follows:

Since interface{} can hold any type of data, by constructing the args, values two arrays, where each value of args points to the address of values corresponding to the value of the data for bulk reading and subsequent operations, it is worth noting that go is a strong type of language, Also, different interface{} have different types of information, and the type conversion is required for the assignment and other related operations.

Go also provides better support for MySQL transaction processing. The general operation is using the method of the DB object, and the transaction is using SQL. The TX object. Use the Begin method of the DB to create a TX object. The TX object also has the query,exec and prepare methods for database interaction, similar to the operation of the DB. After the operation of the query or modification is complete, the commit () commit or rollback () rollback of the TX object needs to be called.

For example, you now need to use a transaction to update the user table you created earlier with the following code

Note: ": =" with "=" Two operators do not confuse

If the transaction does not need to be transacted, the code for update corresponds to the following:

You can compare this with the code that adds the transaction operation above, because the operation is simple, and a few lines of code are added, and the DB object is replaced with the TX object.

Goroutine

Concurrency: Processing (dealing with) different things at the same time
Parallel: doing (doing) different things at the same time

Go supports parallelism from a language level, while Goroutine is the core of go parallel design. Essentially, Goroutine is the co-process, with a separate, self-managed call stack that can be interpreted as a lightweight thread for goroutine. But thread is the operating system scheduling, preemptive-type. The Goroutine is dispatched by its own scheduler.

Scheduler

The Go Scheduler implements the G-P-M scheduling model, which has three important structures: M,p,g

M:machine (OS thread)
P:context (Go Scheduler)
G:goroutine

The underlying data structure looks like this:

The interaction between M, P, and G can be demonstrated by the following diagrams from the Go Runtime scheduler

See, there are 2 physical threads m, each of which has a context p, and a running Goroutine G. The gray ones in the figure do not run, but are ready to be dispatched. This runqueue queue is maintained by P.

The M1 in the diagram may have been created or removed from the thread cache. When M0 returns, it must try to get p to run G, usually it tries to "steal" a p from the other thread and fails, it puts G in a global runqueue and then puts itself into the thread cache. All p will periodically check the global runqueue, otherwise the G on global Runqueue will never be executed.

In another case, the task G assigned by P is executed very quickly (because of uneven distribution), which causes some p to be idle while the system is still in the running state. But if global Runqueue has no task G, then P will have to take some g from the other p to execute. Normally, if p is stealing a task from the other p, it is generally half the ' steal ' runqueue, which ensures that every thread can be used fully.

P How to "steal" from other P-maintained queues to G? This involves the work-stealing algorithm, more information about the algorithm can refer to this article.

G_example

Give a simple example to illustrate how the next goroutine works

This code is very simple, two different goroutine run asynchronously

The results of the operation are as follows:

Then make a minor change, just swap the position of the two functions in main () and change the rest of the code:

There will be an interesting thing:

The reason is also simple, because when main () returns, it does not wait for other goroutine (non-primary goroutine) to end. For the above example, after the main function executes the first say (), a new goroutine is created, and the execution of the program is finished, so the result will appear.

Channel

The goroutine runs in the same address space, so access to shared memory must be synchronized. The go language provides a good communication channel to meet the data communication between Goroutine. The channel is somewhat similar to a two-way pipeline in a Unix shell: it can send or receive values.

Source code

Where the structure of WAITQ is as follows

You can see that the channel is actually a queue plus a lock. Among them, Sendx and RECVX can be seen as producers and consumers queue, respectively, is to wait for the channel on the read operation of the goroutine and wait for the channel to write operations on the Goroutine, as shown in.

The specific implementation of the Write channel (ch <-x) is as follows (only the core code is selected):

It can be divided into three kinds of situations:

    • A goroutine is blocked on the channel, and Chanbuf is empty, sending the data directly to the Goroutine.
    • Chanbuf has space available: put the data into the chanbuf.
    • Chanbuf no space available: blocks the current goroutine.



Read channel (<-CH) and send the operation is similar, do not post code to show.

C_example

A simple example of goroutine communicating with the channel is that the logic is simple:

Here we define two channel jobs and results with the cache, and if the two channel is replaced with no cache, an error will be made, but it can be handled as follows:

More common channel operations also have select, when there are multiple channel, you can monitor the channel data flow through select.

Because both CH1 and CH2 are empty, neither CASE1 nor Case2 will read successfully. The select executes the default statement.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.