Keywords -select go in

1. select use of

  Definition: golang inside the select function epoll (nginx) / poll / select similar functions, they are strong IO operation, when the IO operation occurs, the action is triggered.

1.1 Some of Use

  In the Go language specification, select the order of execution in the case it is random, when there are multiple case can run, select randomly selected a fairly executed, the other will not perform:

 1 package main
 2 
 3 import "fmt"
 4 
 5 func main() {
 6     ch := make (chan int, 1)
 7 
 8     ch<-1
 9     select {
10     case <-ch:
11         fmt.Println("随机一")
12     case <-ch:
13         fmt.Println("随机二n")
14     }
15 }

  A random output content to any twelve inside.

  case must be followed by channel operation, otherwise an error; default clause can always run, so there is no default will block waiting for the select event; the case is not running, then the event will block error (deadlock).

1.2 select application scenarios

Mechanism timeout (timeout determination)
. 1  Package main
 2  
. 3  Import (
 . 4      " FMT " 
. 5      " Time " 
. 6  )
 . 7  
. 8  FUNC main () {
 . 9      timeout: = the make (Chan BOOL , . 1 )
 10      Go FUNC () {
 . 11          time.sleep ( . 1 * Time. SECOND) // sleep 1s, 1s not more than I if the operator believes that timeout has expired notification select it ~ 
12 is          timeout <- to true 
13 is      } ()
 14      CH: = the make (Chan int )
 15      select {
 16     Case <- CH:
 . 17      Case <- timeout:
 18 is          fmt.Println ( " Timeout it! " )
 19      }
 20 }

  You can also write:

. 1  Package main
 2  
. 3  Import (
 . 4      " FMT " 
. 5      " Time " 
. 6  )
 . 7  
. 8  FUNC main () {
 . 9      CH: = the make (Chan int )
 10      SELECT {
 . 11      Case <- CH:
 12 is      Case <-time.After ( * time.Second 1 ): // using the time to realize how much time after the output behalf of the Executive thing after 
13          fmt.Println ( " time out it! " )
 14      }
 15 }

  Determine channel is blocked (or if the channel is already full)

. 1  Package main
 2  
. 3  Import (
 . 4      " FMT " 
. 5  )
 . 6  
. 7  FUNC main () {
 . 8      CH: = the make (Chan int , . 1 )   // Note that given capacity. 1 
. 9      CH <- . 1 
10      SELECT {
 . 11      Case CH <- 2 :
 12 is      default :
 13 is          fmt.Println ( " channel channel it is full, would fit something! " )
 14      }
 15 }

  Exit mechanism

 1 package main
 2 
 3 import (
 4     "fmt"
 5     "time"
 6 )
 7 
 8 func main() {
 9     i := 0
10     ch := make(chan string, 0)
11     defer func() {
12         close(ch)
13     }()
14 
15     go func() {
16         DONE: 
17         for {
18             time.Sleep(1*time.Second)
19             fmt.Println(time.Now().Unix())
20             i++
21 
22             select {
23             case m := <-ch:
24                 println(m)
25                 break DONE // 跳出 select 和 for 循环
26             default:
27             }
28         }
29     }()
30 
31     time.Sleep(time.Second * 4)
32     ch<-"stop"
33 }

2. select the realization

  chan operations have been compiled in the select-case became the if-else. Such as:

1  select {
2  case v = <-c:
3          ...foo
4  default:
5          ...bar
6  }

  It will be compiled as follows:

1  if selectnbrecv(&v, c) {
2          ...foo
3  } else {
4          ...bar
5  }

  Similarly

1  select {
2  case v, ok = <-c:
3      ... foo
4  default:
5      ... bar
6  }

  It will be compiled as follows:

1  if c != nil && selectnbrecv2(&v, &ok, c) {
2      ... foo
3  } else {
4      ... bar
5  }

  selectnbrecv function simply calls runtime.chanrecv function, but set a parameter that tells when runtime.chanrecv function, when you can not complete the operation do not block, but returns a failure. In other words, all of the select operation in fact merely been replaced by a judge if-else, do not block the passage underlying operating function call.

  In the Go language specification, select the order of execution in the case is random, then, how random it?

  select and use the keyword case the following structure:

1 struct    Scase
2   {
3       SudoG    sg;            // must be first member (cast to Scase)
4       Hchan*    chan;        // chan
5       byte*    pc;            // return pc
6       uint16    kind;
7       uint16    so;            // vararg of selected bool
8       bool*    receivedp;    // pointer to received bool (recv2)
9   };
. 1   struct     the Select
 2       {
 . 3       UInt16 TCASE;             // total scase [] number 
. 4       UInt16 ncase;             // current of filled scase [] number 
. 5       UInt16 * pollorder;         // poll in order case 
. 6       Hchan ** lockorder;         // order of locked channel 
. 7       Scase scase [ . 1 ];         // each case will have a structure in Scase, the order is the order of appearance of 
8   };

  Each corresponds to a select Select structure. There Scase array recorded in every case Select data structure, and contains Scase Hchan. Then the array elements are arranged randomly pollorder, so that you can be a Scase scrambled.

 3. select deadlock

  We will not pay attention to select a deadlock occurs, two possibilities:

  If there is no data to be transmitted, and in the presence of SELECT statements received channel data, then the transmission will deadlocks

1 package main
2 func main() {  
3     ch := make(chan string)
4     select {
5     case <-ch:
6     }
7 }

  Prevention of words plus default.

  Empty select, will lead to a deadlock.

1 package main
2 
3 func main() {  
4     select {}
5 }

 4. select switch and distinguish the

select

select channel operation can only be applied, may be used for data reception channel, the channel may also be used for data transmission. If a plurality of conditions are satisfied select branches, wherein the branch will randomly select a satisfied condition, as in the specification:
If multiple cases can proceed, a uniform pseudo-random choice is made to decide which single communication will execute.
Expression `case` statement can be assigned to a variable or two variables. There are default statement.
31 package main                                                                                                                                              32 import "time"
33 import "fmt"                                                                                                                                              
35 func main() {                                                                                                                                             36     c1 := make(chan string)
37     c2 := make(chan string)                                                                                                                               38     go func() {
39         time.Sleep(time.Second * 1)                                                                                                                       40         c1 <- "one"
41     }()                                                                                                                                                   42     go func() {
43         time.Sleep(time.Second * 2)                                                                                                                       44         c2 <- "two"
45     }()                                                                                                                                                   46     for i := 0; i < 2; i++ {
47         select {                                                                                                                                          48             case msg1 := <-c1:
49             fmt.Println("received", msg1)          
50 case msg2 := <-c2: 51 fmt.Println("received", msg2)
52 } 53 }

switch

  branching operation switch may be of various types, settings can be determined that the interface type branched (by i. (type)). switch branches are executed sequentially, and which select different.
 1 package main                  
 2 import "fmt"
 3 import "time"  
 4 
 5 func main() {                                                                                                                             
 6      i := 2
 7      fmt.Print("Write ", i, " as ")  
 8      switch i {
 9          case 1:
10          fmt.Println("one")
11          case 2:                                                                                                                                  
12          fmt.Println("two")
13          case 3:                                                                                                                      
14          fmt.Println("three")
15      }                                                                                                                                             
16      switch time.Now().Weekday() {
17          case time.Saturday, time.Sunday:
18          fmt.Println("It's the weekend")
19          default:                                                                                                                                      
20          fmt.Println("It's a weekday")
21      }                                                                                                                                                 
22      t := time.Now()
23      switch {                                                                                                                                         
24          case t.Hour() < 12:
25          fmt.Println("It's before noon")                                                                                                              
26          default:
27          fmt.Println("It's after noon")                                                                                                                  
28      }
29      whatAmI := func(i interface{}) {                                                                                                                   
30          switch t := i.(type) {
31              case bool:                                                                                                                              
32              fmt.Println("I'm a bool")
33              case int:                                                                                                                                 
34              fmt.Println("I'm an int")
35              default:                                                                                                                                 
36              fmt.Printf("Don't know type %T\n", t)
37          }
38      }
39      whatAmI(true)                                                                                                                                     
40      whatAmI(1)
41      whatAmI("hey")                                                                                                                                 
42  }

 

Guess you like

Origin www.cnblogs.com/33debug/p/11891154.html