Basic features of Go channel

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

This article introduces Go Channel

What is Goroutine

They ' re called Goroutines because the existing terms-threads, coroutines, processes, and so on-convey inaccurate Conno Tations. A goroutine have a simple model:it are a function executing in parallel with other goroutines in the same address space. It is lightweight, costing little more than the allocation of stack space. And the stacks start small, so they is cheap, and grow by allocating (and freeing) heap storage as required.

As the official says, Goroutine is a lightweight execution unit that is responsible for scheduling from the go language and is the core of Go support concurrency, compared to a smaller thread overhead. Opening a goroutine is very simple:

1234567891011
 Package mainimport ("FMT""Time")funcmain() {go fmt. Println ("goroutine message") time. Sleep (1//1fmt. PRINTLN ("main function Message")}

#1The code is required, this is to allow the newly opened goroutine to be executed, after opening a goroutine, the subsequent code will continue to execute, in the above example, the subsequent code execution is terminated, and the open goroutine may not have begun to execute.

If you try to #1 get rid of the code, the program may also run normally, because the goroutine that happens to be turned on simply executes the output once, and if the goroutine takes a little longer it will cause you to see only the main sentence main function message .

In other words, time.sleep What is provided here is a scheduling mechanism, which is the purpose of the channel presence in GO: responsible for message delivery and scheduling.

Channel

The channel is a communication mechanism provided for goroutine in Go, which has a type and direction, and can be used to analogy the channel to a pipe in UNIX.

1234
 Make (chanint) //int Type  Make (chanstring) //String type  Make (<-Chanbool) //read-only  Make (Chan<-[]int) //write only

The most important function of the Channel is to deliver the message.

 package  mainimport  (  "FMT" ) func  main   ()   {c: = make  (chan   int ) go  func   ()   {fmt. Println ( "goroutine message" ) c <-1  //1 } () <-c //2  fmt. Println ( "main function message" )} 
 1234567891011121314 

The example declares a channel of type int, #1 sends data to the channel in Goroutine, 1 waits for data to be received in main, and #2 if there is no data in C, the execution of the code is blocked until C The data is received. This is one of the simplest uses of the channel: synchronous, this type of channel does not have the capacity to be called the unbuffered channel.

Unbuffered Channel and buffered channel

The channel can set the capacity, indicating the number of messages that the channel is allowed to receive, the default channel capacity is 0 called the unbuffered channel , and the unbuffered channel performs read operations As value: = <-ch will block until there is data to be received, and the write operation Ch <-value will block until there is a goroutine on the channel to start receiving, because so in the same goroutine The use of unbuffered channel in the deadlock will cause the

1234567891011
 Package mainimport ("FMT")func-main()make (chanint1<-cfmt. PRINTLN ("main function Message")}

The executive newspaper fatal error: all goroutines are asleep - deadlock! , read and write each other waits for each other thereby causing the deadlock to occur.

If the channel capacity is not 0, this type of channel is called the buffered channel , and the buffered channel does not block until the number of message writes reaches the maximum capacity , once the message is written to a Number exceeds the limit, the next input will block until the channel has a position to be written again.

 123456789101112131415161718 
 package  mainimport  () func  main   ()   {c: = make  (chan  int , 3 ) go   func   ()   {for  i: = 0 ; i < Span class= "number" >4 ; i++ {c <-ifmt. Println ( "write to C" , I)}} () for  i: = 0 ; I < 4 ; i++ {fmt. Println ( "reading" , <-c)}} 

The above example will output:

12345678
0 0 1 1 2 2 3 3

According to the above interpretation of the buffered channel, the channel capacity in this example c is 3, does not block when the number of messages written does not exceed 3, the output should be:

12345678
0 1 2 0 1 2 3 3

Where's the problem? The problem is fmt.Println that once the output causes the execution of the goroutine to switch (equivalent to an IO block), so even if C does not have a blocking goroutine will let go, together to verify the problem.

12345678910111213141516171819202122232425262728
 PackageMainImport("FMT""StrConv") func main() {c: = Make(Chan int,3) S: = Make([]string,8)varNumint=0Go  func() { forI: =0; I <4; i++ {c <-inum++v: ="Inner=>"+ StrConv. Itoa (num) s =Append(S, v)}} () forI: =0; I <4; i++ {<-cnum++v: ="Outer=>"+ StrConv. Itoa (num) s =Append(S, v)} Fmt. Println (s)}

Here a slice is created to hold C for write and read execution order, NUM is used to identify the order of execution, before Println is added, the final S is [inner=>1 inner=>2 inner=>3 inner=>4 Outer=>5 outer=>6 outer=>7 outer=>8], the output indicates that C will not block until it reaches the capacity to go online.

Instead there are output statements that have a different version result:

1234567891011121314151617181920212223242526272829
 PackageMainImport("FMT""StrConv") func main() {c: = Make(Chan int,3) S: = Make([]string,8)varNumint=0Go  func() { forI: =0; I <4; i++ {c <-inum++v: ="Inner=>"+ StrConv. Itoa (num) s =Append(S, v) fmt. Println ("Write to C", i)}} () forI: =0; I <4; i++ {num++v: ="Outer=>"+ StrConv. Itoa (num) s =Append(S, v) fmt. Println ("reading", <-c)}fmt. Println (s)}

[Outer=>1 inner=>2 outer=>3 inner=>4 inner=>5 inner=>6 outer=>7 outer=>8] Output results can show two goroutine Is alternately executed, that is, the IO call Println causes Goroutine to give up execution.

Read messages from multiple channel

GO provides a SELECT statement to handle message reads from multiple channel.

123456789101112131415161718192021222324252627282930313233343536373839
 PackageMainImport("FMT""Time") func main() {c1: = Make(Chan string) C2: = Make(Chan string)Go  func() { for{C1 <-"from 1"Time. Sleep (time. Second *2)}}()Go  func() { for{C2 <-"from 2"Time. Sleep (time. Second *2)}}()Go  func() { for{Select{ CaseMSG1: = <-c1:fmt. Println (MSG1) CaseMSG2: = <-c2:fmt. Println (MSG2)}}} ()varInputstringFmt. Scanln (&input)}

Select statements can be randomly selected from a number of readable channel and are randomly selected.

After the Channel is closed

The

Channel can be closed close , the channel can still be read after it is closed , if the channel is closed before the value is written, after closing, the message in the Channel will be read sequentially. The zero value of the type that will return the channel is read again after the reading is finished:

 123456789101112131415161718192021 
 package  mainimport  ( "FMT" ) func  main   ()   {c: = make  (chan  int , 3 ) go  func   ()   {c <- 1  C <-2  C <-3  close  (c)} () Fmt. Println (<-c) fmt. Println (<-c) fmt. Println (<-c) fmt. Println (<-c) fmt. Println (<-c) fmt. Println (<-c)} 

Output 1 2 3 0 0 0, 0 is the zero value of the INT channel C.

the closed channel can be a range iteration :

 123456789101112131415161718 
 package  mainimport  () func  main  Span class= "params" > ()   {c: = make  (chan  span class= "keyword" >int , 3 ) go  func   ()   {c <-1  C <-2  C <-3  Span class= "built_in" >close  (c)} () for  i: = range  c { Fmt. Println (i)}} 

A channel that is not closed does not, and if it is not closed, the range will block until the message in the channel is finished and deadlock occurs.

Resources

    • Https://www.miek.nl/go
    • Http://guzalexander.com/2013/12/06/golang-channels-tutorial.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.