"Turn" Golang about channel Chan

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

Original: http://blog.csdn.net/netdxy/article/details/54564436

When using Chan type, there is a deadlock error and there is nothing on the surface.

-------------------------------------------------------------------------------------------------------

First we look at the thread, inside the Golang is also called Goroutine

Before reading this article, we need to look at concurrency and parallelism. Golang threads are a concurrency mechanism, not parallel. The difference between them you can search the Internet, there are many online introduction.

Let's take a look at an example.

Import (         "FMT") Funcmain () {    go fmt. Println ("1")    FMT. Println ("2")    }

In Golang, you can create a thread with the Go keyword, followed by a function. The following function can be a function that has already been written, or it can be an anonymous function.

Funcmain () {    var i=3    go func (a int) {        fmt. Println (a)        FMT. Println ("1")    } (i)    FMT. Println ("2")}

The above code creates an anonymous function, and also passes in a parameter I, where I is an argument, and a is a formal parameter.

So can the above code print 1, 2, 3 as we expect? Tell you, no, the program can only print 2. I'll post the correct code.

Import (    "FMT"    "Time"    ) Funcmain () {    var i = 3    go func (a int) {        fmt. Println (a)        FMT. Println ("1")    } (i)    FMT. Println ("2") Time    . Sleep (1 * time. Second)}

I just added a line at the end of the code that lets the main thread sleep for a second, and the program prints 2, 3, and 1 in turn.

Then why is that? Because the program takes precedence over the main thread, the program exits immediately after the main thread executes, and there is no extra time to execute the child threads. If the main thread sleeps for 1 seconds at the end of the program, the program will have enough time to execute the child threads.

Line enters upgradeable here, let's take a look at the channel.

Channels are called Channel, as the name implies, the role of channel is to pass data between multithreading.

Create unbuffered Channel

Chreadandwrite: =make (chan int)

Chonlyread: = make (<-chan int)//create read-only channel
Chonlywrite: = make (chan<-int)//create write-only channel
Let's look at an example:

Ch: =make (chan int)         ch <-1      Go func () {        <-ch        fmt. Println ("1")      } ()      FMT. Println ("2")  

An error occurs when this code executes: Fatal Error:all Goroutines is asleep-deadlock!

This error means that the thread is stuck in a deadlock and the program cannot continue to execute. So what is the cause of this mistake?

we created a non-buffered channel and then assigned the channel, and the program was locked into a deadlock after the assignment was completed. Because our channel is unbuffered, that is, synchronous, when the assignment is too late to read the channel, the program is blocked . Here is a very important concept: the channel mechanism is FIFO, if you assign the channel, then you must read its value, otherwise it will cause blocking, of course, this is only valid for unbuffered channel. For buffered channel, the sender blocks until the data is copied to the buffer, and if the buffer is full, the sender can recover from the blocking state only after the receiver has taken away the data.

There are two solutions for the above example:

1, add buffer to channel, and then at the end of the program let the main thread sleep for one second, the code is as follows:

Ch: =make (chan int,1)    ch <-1    Go func () {        V: = <-ch        fmt. Println (v)    } () Time    . Sleep (1 * time. Second)    FMT. Println ("2")

In this case, the program will print 1, 2

2, put ch<-1 this line of code behind the child Thread Code, the code is as follows:

Ch: =make (chan int)    go func () {        V: = <-ch        fmt. Println (v)    } ()    ch <-1    fmt. Println ("2")

  

There is no need for the main thread to hibernate, since the channel is assigned a value in the main thread, and the main thread blocks until the value of the channel is taken out of the child thread.

Finally, let's look at a producer and consumer example:

Import (    "FMT"    "Time") func produce (p chan<-int) {for    I: = 0; i <; i++ {        p <-i        fmt. Println ("Send:", i)    }}func consumer (c <-chan int) {for    I: = 0; I < 10; i++ {        V: = <-c        fmt. Println ("Receive:", v)    }}func Main () {    ch: = make (chan int)    go Produce (CH)    Go Consumer (CH)    Time. Sleep (1 * time. Second)}

  

In this code, because the channel is not buffered, when the producer assigns the channel, the producer will block until the consumer thread takes the data out of the channel. After the consumer first pulls the data out, the next cycle occurs, and the consumer's thread is blocked because the producer has not yet deposited the data, and the program executes the producer's thread. The program then switches between the consumer and the producer two threads until the loop is over.

Let's look at another example with buffering:

Import (    "FMT"    "Time") func produce (p chan<-int) {for    I: = 0; i <; i++ {        p <-i        fmt. Println ("Send:", i)    }}func consumer (c <-chan int) {for    I: = 0; I < 10; i++ {        V: = <-c        fmt. Println ("Receive:", v)    }}func Main () {    ch: = Make (chan int, ten)    go Produce (CH)    Go Consumer (CH)    Time. Sleep (1 * time. Second)}

In this program, the buffer can store 10 integers of type int, while executing the producer thread, the thread will not block, and the 10 integers will be saved to the channel at a time, and also read at once.

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.