Go language concurrency

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

Concurrent

Some people compare go to the C language of the 21st century, the first is because the go language design is simple, second, the 21st century most important is the parallel programming, and go from the language level to support the parallel.

Goroutine

Goroutine is the core of go parallel design. Goroutine In fact is a thread, but it is smaller than the thread, more than 10 goroutine may be reflected in the bottom is five or six threads, the go language inside to help you achieve the memory sharing between these goroutine. Execution goroutine requires very little stack memory (presumably 4~5kb) and will, of course, scale according to the corresponding data. Because of this, thousands of concurrent tasks can be run concurrently. Goroutine is easier to use, more efficient and lighter than thread.

Goroutine is a thread manager managed through the runtime of Go. Goroutine go is implemented by the keyword, which is actually a normal function.

Go Hello (A, B, c)

A goroutine is launched via the keyword go. Let's look at an example

Package Mainimport (    "FMT"    "runtime") Func say (s string) {for    I: = 0; i < 5; i++ {        runtime. Gosched ()        FMT. Println (s)    }}func main () {    go Say ("world")//Open a new Goroutines execution    say ("Hello")//current Goroutines execution}// After executing the above program will output://hello//world//hello//world//hello//world//hello//world//Hello

We can see that the Go keyword is very handy for concurrent programming. The above multiple goroutine run in the same process, sharing the memory data, but the design we want to follow: do not communicate through sharing, but to be shared through communication.

runtime. Gosched () means that the CPU will give the time slice to others, and the next time it resumes executing the goroutine.

By default, the scheduler uses only a single thread, meaning that only concurrency is implemented. To play parallel with multicore processors, you need to explicitly call runtime in our program. Gomaxprocs (N) tells the scheduler to use multiple threads at the same time. Gomaxprocs sets the maximum number of system threads that are running logic code at the same time, and returns the previous settings. If n < 1, the current setting is not changed. After the schedule is improved in the new version of Go, this is removed. Here's an article about concurrency and parallelism that Rob introduces: Http://concur.rspace.googlecode.com/hg/talk/concur.html#landing-slide

Channels

The goroutine runs in the same address space, so access to shared memory must be well synchronized. So how does data communicate between Goroutine, go provides a good communication mechanism channel. The channel can be analogous to a bidirectional pipeline in a Unix shell: it can send or receive values. These values can only be of a specific type: Channel type. When defining a channel, you also need to define the type of value sent to the channel. Note that you must use make to create the channel:

CI: = make (chan int) cs: = Do (chan string) CF: = Make (chan interface{})

Channel via operator <- to receive and send data

Ch <-v    //Send V to channel CH.V: = <-ch  //Receive data from CH and assign to V

Let's apply these to our example:

package mainimport" FMT "func sum (a []int, C Chan int) {total: = 0 for _, V: = RA  Nge a {total + = v} c <-Total//Send all to C}func main () {a: = []int{7, 2, 8,-9, 4, 0} c: = Make (chan int) go sum (A[:len (a)/2], C) Go sum (A[len (a)/2:], c) x, y: = <-c, <-c//Receive from C FMT. Println (x, y, x + y)} 

By default, the channel receives and sends data to be blocked, unless the other end is ready, which makes the Goroutines synchronization much simpler, without the need for an explicit lock. The so-called blocking, that is, if read (value: = <-ch) It will be blocked until data is received. Second, any send (ch<-5) will be blocked until the data is read out. Unbuffered Channel is a great tool for synchronizing between multiple goroutine.

Buffered Channels

We have described the default non-cached channel, but go also allows you to specify the buffer size of the channel, which is simply how many elements the channel can store. ch:= make (chan bool, 4) Creates a bool-type channel that can store 4 elements. In this channel, the first 4 elements can be written without blocking. When the 5th element is written, the code blocks until the other goroutine reads some elements from the channel, freeing up space.

CH: = Make (chan type, value) value = = 0! No buffering (blocking) value > 0! Buffering (non-blocking until value elements)

Let's take a look at the following example, you can test it on your own machine, modify the corresponding value value

Package Mainimport "FMT" Func Main () {    c: = make (chan int, 2)//modify 2 to 1 for error, modify 2 to 3 to operate normally    C <-    1 c <-2    FMT . Println (<-c)    FMT. Println (<-C)}    //modified to 1 reported error:    //fatal error:all Goroutines is asleep-deadlock!

Range and close

In this example, we need to read two times C, which is not very convenient, go considering this, so you can also use range, like operation slice or map to manipulate the buffer type of channel, see the following example

package mainimport (" FMT ") func Fibonacci (n int, c Chan int) {x, Y: = 1, 1 fo R I: = 0; I < n; i++ {c <-x x, y = y, x + y} close (c)}func main () {c: = make (chan int, ten) go Fibonacci (ca P (c), C) for I: = Range C {fmt. Println (i)}} 

for I: = range C is able to continuously read the data inside the channel until the channel is explicitly closed. The above code we see can be explicitly closed channel, producer via built-in function close to close the channel. After the channel is closed, no more data can be sent, in the consumer's grammar v, OK: = <-ch The test channel is closed. If OK returns false, then the channel has no data and has been closed.

Remember that the channel should be closed at the producer's place, not where it is consumed, so it can easily cause panic

Another thing to remember is that the channel is not like a file, and you don't have to close it often, only if you really don't have any data to send, or you want to explicitly end the range loop.

Select

What we've described above is only one channel, so if there's more than one channel, how do we do it, and go provides a keyword select , through select can listen for data flow on the channel.

select is blocked by default and only runs when there is a send or receive in the channel being monitored, and when multiple channel is ready, select is randomly selected to execute.

package mainimport" FMT "func Fibonacci (c, quit Chan int) {x, Y: = 1, 1 for { Select {Case C <-x:x, y = y, x + y case <-quit:fmt. Println ("Quit") return}}}func main () {c: = Make (Chan int.) Quit: = make (chan int) go func ( {for I: = 0; i <; i++ {FMT. Println (<-C)} quit <-0} () Fibonacci (C, quit)} 

There is the default select syntax, in select fact, is similar to switch function, the default is when the channel is not ready to listen to the time, the defaults (select no longer block waiting for the channel).

Select {case I: = <-c:    //Use Idefault:    //When C is blocked execute here}

Timeout

Sometimes there is a case of goroutine blocking, so how do we avoid the whole program getting stuck? We can use Select to set the timeout, which is implemented in the following way:

Func Main () {    c: = Make (chan int.)    o: = Make (chan bool)    go func () {for        {            Select {case                V: = <- C:                    println (v) Case                <-time. After (5 * time. Second):                    println ("timeout")                    o <-true                    break            }        }}    ()    <-o}

Runtime Goroutine

There are several functions in the runtime package that deal with Goroutine:

  • Goexit

    Exits the currently executing goroutine, but the defer function also continues to invoke the

  • Gosched

    With the execution permission of the current goroutine, the scheduler schedules other waiting tasks to run and resumes execution from that location at some point.

  • Numcpu

    Returns the number of CPU cores

  • Numgoroutine

    Returns the total number of tasks being executed and queued

  • Gomaxprocs

    Used to set the maximum number of CPU cores that can be computed in parallel and return the previous value.

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.