Deep learning Golang (2)-channel

Source: Internet
Author: User

Channel

1. Overview

"Network, concurrency" is the two big feature of Go language. The go language, known as the "C language of the Internet", uses less code and is simpler to write a server than the traditional C language. Write a server In addition to the network, but also concurrency, relative to Python and other languages, go to the concurrency support so that it has better performance.

Goroutine and channel are two core feature of go in "concurrency".

The channel is a way of communicating between Goroutine and it is similar to a pipeline in UNIX.

Channel statement:

Channeltype = ("Chan" | "Chan" "<-" | "<-" "Chan") ElementType.

For example:

var ch Chan int

var ch1 chan<-int//ch1 can only be written

var ch2 <-chan int//CH2 Read Only

The channel is type-dependent, i.e. a channel can only pass one type. For example, the upper CH can only pass int.

In the go language, there are 4 types of reference: Slice,map,channel,interface.

Slice,map,channel is typically initialized with make:

CI: = make (chan int)//unbuffered channel of integers

CJ: = Make (chan int, 0)//unbuffered channel of integers

CS: = Make (chan *os. File, +)//buffered channel of pointers to Files

When you create a channel, you can provide an optional integer parameter that sets the buffer size for the channel. The value defaults to 0, which is used to build the default "Unbuffered channel", also known as "synchronous channel."

Channel as a communication mechanism between goroutine, similar to other communication mechanisms of the operating system, there are generally two purposes: synchronization, or delivery of messages.

2. Synchronization

c: = make (chan int)//Allocate a channel.

Start the sort in a goroutine; When it completes, signal on the channel.

Go func () {

List. Sort ()

C <-1//Send a signal; Value does not matter.

}()

Dosomethingforawhile ()

<-C//Wait for sort to finish; Discard sent value.

In the example above, the sort operation in the child Goroutine, the main goroutine can do something else, and then wait for the goroutine to finish sorting.

The receiver will block until there is data coming. If the channel is unbuffered, the sender blocks until the receiver pulls the data out. If the channel has a buffer, 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.

3. Message Delivery

Let's simulate the classic producer-consumer model.

Func Producer (Queue chan<-int) {

For i:= 0; I < 10; i++ {

Queue <-I

}

}

Func Consumer (Queue <-chan int) {

For I: = 0; I < 10; i++{

V: = <-queue

Fmt. Println ("Receive:", V)

}

}

Func Main () {

Queue: = Make (chan int, 1)

Go Producer (queue)

Go Consumer (queue)

Time. Sleep (1E9)//Let producer and consumer complete

}

The above example generates data in producer and processes the data in consumer.

4. Server programming Model

In server programming, a common model: the main thread receives the request and then distributes the request to the worker thread, which completes the request processing. Use go to achieve, as follows:

Func handle (R *request) {

Process (R)//may take a long time.

}

Func Serve (Queue Chan *request) {

for {

Req: = <-queue

Go handle (req)//Don ' t wait for handle to finish.

}

}

In general, the processing power of the server is not unlimited, so it is necessary to limit the number of threads (or goroutine). We usually do this through the signal volume, and in go we can achieve the same effect through the channel:

var sem = Make (chan int, maxoutstanding)

 

func handle (R *request) {

    sem <-1 & nbsp;  //Wait for the active queue to drain.

    process (R)   //may take a long time.

    <-sem       //done; enable next Request to run.

&NBSP;

func serve (queue chan *request) {

    for {

         req := <-queue

        go handle ( Req)   //Don ' t wait for handle to finish.

&NBSP;&NBSP;&NBSP;&NBSP;}

By introducing the SEM channel, we limit the simultaneous operation of up to Maxoutstanding Goroutine. However, the above approach only limits the number of goroutine that are running, and does not limit the number of goroutine generated. If the request arrives too fast, it can result in a lot of goroutine, which can result in complete system resource consumption.

To do this, it is necessary to limit the number of Goroutine created:

Func Serve (Queue Chan *request) {

For req: = Range Queue {

SEM <-1

Go func () {

Process (req)//Buggy; See explanation below.

<-sem

}()

}

}

The code above seems simple and clear, but in go, there is a problem. The loop variables in the go language are reused in each iteration, and more directly, req is shared across all sub-goroutine, and variable req is global to all goroutine from the scope of the variable.

This problem belongs to the realm of language implementation, in C, you should not pass a local variable to another thread to handle. There are a lot of workarounds, here's a discussion. Personally, I prefer the following approach:

Func Serve (Queue Chan *request) {

For req: = Range Queue {

SEM <-1

Go func (R *request) {

Process (R)

<-sem

} (req)

}

}

At the very least, such a code will not make a go beginner to be confused, in addition, from the scope of the variables, but also more common sense.

In the real C + + programming, we tend to create a worker thread at the beginning, and the number of threads is fixed. In go, we can also do this:

Func handle (Queue Chan *request) {

For r: = Range Queue {

Process (R)

}

}

Func Serve (Clientrequests Chan *request, quit Chan bool) {

Start handlers

For I: = 0; i < maxoutstanding; i++ {

Go handle (clientrequests)

}

<-quit//Wait to being told to exit.

}

Starting with a fixed number of handle Goroutine, each goroutine reads the request directly from the channel. This kind of writing is relatively simple, but do not know whether there is a "surprise group" problem? The implementation of Goroutine for subsequent analysis is needed.

5. Channel for transmitting channel

As a native type of the go language, the channel can naturally be passed through the channel. Passing the channel through the channel can be a very simple and graceful solution to some practical problems.

In the previous section, our main goroutine passes the request through the channel to the working goroutine. Similarly, we can also return the processing results to the main goroutine by channel.

Main Goroutine:

Type Request struct {

args []int

Resultchan Chan int

}

Request: = &request{[]int{3, 4, 5}, make (chan int)}

Send Request

Clientrequests <-Request

Wait for response.

Fmt. Printf ("Answer:%d\n", <-request.resultchan)

The Master Goroutine requests the request channel and waits for the result channel to be sent. When the child goroutine finishes processing, the result is written to the result channel.

Func handle (Queue Chan *request) {

For req: = Range Queue {

Result: = Do_something ()

Req.resultchan <-Result

}

}

6. Multiple channel

In practical programming, you often encounter situations where multiple channel is handled in a goroutine. We can't block two channel, and that's the Select field. Like the Select in C can monitor multiple FD, select in the Go language can wait for multiple channel.

C1: = Make (Chan string)

C2: = Make (Chan string)

Go func () {

Time. Sleep (time. Second * 1)

C1 <-"One"

}()

Go func () {

Time. Sleep (time. Second * 2)

C2 <-"The other"

}()

For I: = 0; I < 2; i++ {

Select {

Case MSG1: = <-c1:

Fmt. Println ("received", MSG1)

Case MSG2: = <-c2:

Fmt. Println ("received", MSG2)

}

}

In C, we generally pass a time-out to the Select function, and select in the go language does not have this parameter, which is equivalent to a timeout of 0.

Main references

Https://golang.org/doc/effective_go.html

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.