Featured image of post 《Go专家编程》读书笔记 | 第2章 控制结构 | 综合篇

《Go专家编程》读书笔记 | 第2章 控制结构 | 综合篇

select特性综述🟠

系列文章

同系列其它文章

全部问题

1
2
3
4
5
--------------------------------------------------------------------------------------
| ID | UpdateTime          | Question
--------------------------------------------------------------------------------------
| 1  | 2024-03-05 18:40:25 | select特性综述
--------------------------------------------------------------------------------------

select特性综述

🌞 ︎阳历 2024年03月05日 星期二 | 🌙农历 龙年(2024)正月廿五 | 🕛晚上 6点40分25秒 | 更新 🏳️‍🌈

select特性综述
1   先介绍一下select的case语句。
  说一下select的case阻塞条件。
  说一下select的全部case阻塞后会怎么样。
  说一下select的多个case都没有阻塞会怎么样。
  1. select的case语句基本特点select的case语句每次只能操作一个管道,要么写入数据,要么读取数据
  2. select的case阻塞的条件鉴于管道的特性,如果管道中没有数据读取操作则会阻塞,如果管道中没有空余的缓冲区则写入操作会阻塞
  3. select的全部case阻塞后会怎么样当select的多个case语句中的管道均阻塞时,整个select语句也会陷入阻塞(没有default的情况下),直到任意一个管道解除阻塞。
  4. select的多个case都没有阻塞会怎么样如果多个case语句均没有阻塞,那么select将随机挑选一个case执行
2   先介绍一下select的case语句。
  说一下select的case阻塞条件。
  说一下select的全部case阻塞后会怎么样。
  说一下select的多个case都没有阻塞会怎么样。
  1. select的case语句基本特点select的case语句每次只能操作一个管道,要么写入数据,要么读取数据
  2. select的case阻塞的条件鉴于管道的特性,如果管道中没有数据读取操作则会阻塞,如果管道中没有空余的缓冲区则写入操作会阻塞
  3. select的全部case阻塞后会怎么样当select的多个case语句中的管道均阻塞时,整个select语句也会陷入阻塞(没有default的情况下),直到任意一个管道解除阻塞。
  4. select的多个case都没有阻塞会怎么样如果多个case语句均没有阻塞,那么select将随机挑选一个case执行

示例代码

源码链接 stdlib/runtime/select/features_and_usages/comprehensive/001_test.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package comprehensive

import (
  "fmt"
  "testing"
  "time"

  selecttools "github.com/gainovel/testcase/stdlib/runtime/select/tools"
  commonprint "github.com/gainovel/testcase/tools/common/print"
)

var (
  myfmt = commonprint.MyFmt
)

func TestName_2024_03_13_10_44_15(t *testing.T) {
  // select的case语句基本特点
  // go test -v -run TestName_2024_03_13_10_44_15/case1 github.com/gainovel/testcase/stdlib/runtime/select/features_and_usages/comprehensive
  t.Run("case1", func(t *testing.T) {
    var (
      ch1 chan int
      ch2 chan int
    )
    ch1 = make(chan int, 2)
    ch2 = make(chan int)
    myfmt.VarInitPrintln(`    var (
      ch1 chan int
      ch2 chan int
    )
    ch1 = make(chan int, 2)
    ch2 = make(chan int)`)
    myfmt.ColorDescPrintln("go tools.SendToIntChan(ch2)", `func SendToIntChanNTimes(ch chan int, n int) {
  for i := 0; i < n; i++ {
    ch <- i
    time.Sleep(time.Second)
  }
}`)
    go selecttools.SendToIntChanNTimes(ch2, 3)
  label1:
    for {
      select {
      case ch1 <- 1:
        myfmt.ColorDescPrintln("进入case ch1 <- 1")
        myfmt.KeyValuePrintln("len(ch1)", len(ch1), "cap(ch1)", cap(ch1))
        val, ok := <-ch1
        myfmt.ColorDescPrintln("val, ok := <-ch1")
        myfmt.KeyValuePrintln("len(ch1)", len(ch1), "cap(ch1)", cap(ch1), "val", val, "ok", ok)
        time.Sleep(time.Second)
      case val, ok := <-ch2:
        myfmt.ColorDescPrintln("进入case val, ok := <-ch2")
        myfmt.KeyValuePrintln("len(ch2)", len(ch2), "cap(ch2)", cap(ch2), "val", val, "ok", ok)
        if val == 2 {
          break label1
        }
        time.Sleep(time.Second)
      default:
        fmt.Println("进入case default")
      }
    }
  })
  t.Run("read block", func(t *testing.T) {
    var (
      ch1 chan int
    )
    ch1 = make(chan int, 2)
    // 如果没有一个goroutine在运行,go进程会停止,
    // 所以这里放一个sleep goroutine
    go selecttools.SleepGoroutineNMinute(5)
    // ch1缓冲区无数据,select会阻塞
    select {
    case <-ch1:
      myfmt.ColorDescPrintln("进入 case <-ch1")
    }
  })
}

输出结果

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
**************************************************************************************
* 测试用例运行方法
*  0.前置要求安装goversion>=1.20),安装make可选
*  1.git clone git@gitee.com:gainovel/go-test-case.git 👉 cd go-test-case
*    👉 cd docs/tests/stdlib/runtime/select.md
*    👉 找到对应的命令依次复制执行即可在根目录go-test-case下执行命令
*  2.或者直接打开测试文件 stdlib/runtime/select/features_and_usages/comprehensive/001.go
*    每个子测试上都有对应的命令直接执行即可在根目录go-test-case下执行命令
*  3.  注意所有命令都在根目录下执行
**************************************************************************************

🏳️‍🌈
**************************************************************************************
*  Test Command: make TestName_2024_03_13_10_44_15/case1 -f Makefiles/stdlib/runtime/select.mk
*  Test Result:
*  👇
*  变量初始化
*  --------------------------------------------------------------------------------
*                  var (
*                          ch1 chan int
*                          ch2 chan int
*                  )
*                  ch1 = make(chan int, 2)
*                  ch2 = make(chan int)
*  --------------------------------------------------------------------------------
*  👇
*  go tools.SendToIntChan(ch2)
*  func SendToIntChanNTimes(ch chan int, n int) {
*          for i := 0; i < n; i++ {
*                  ch <- i
*                  time.Sleep(time.Second)
*          }
*  }
*  👇
*  进入case ch1 <- 1
*  --------------------------------------------------------------------------------
*  |               key | value
*  --------------------------------------------------------------------------------
*  |          len(ch1) | 1
*  |          cap(ch1) | 2
*  --------------------------------------------------------------------------------
*  👇
*  val, ok := <-ch1
*  --------------------------------------------------------------------------------
*  |               key | value
*  --------------------------------------------------------------------------------
*  |          len(ch1) | 0
*  |          cap(ch1) | 2
*  |               val | 1
*  |                ok | true
*  --------------------------------------------------------------------------------
*  👇
*  进入case val, ok := <-ch2
*  --------------------------------------------------------------------------------
*  |               key | value
*  --------------------------------------------------------------------------------
*  |          len(ch2) | 0
*  |          cap(ch2) | 0
*  |               val | 0
*  |                ok | true
*  --------------------------------------------------------------------------------
*  👇
*  进入case ch1 <- 1
*  --------------------------------------------------------------------------------
*  |               key | value
*  --------------------------------------------------------------------------------
*  |          len(ch1) | 1
*  |          cap(ch1) | 2
*  --------------------------------------------------------------------------------
*  👇
*  val, ok := <-ch1
*  --------------------------------------------------------------------------------
*  |               key | value
*  --------------------------------------------------------------------------------
*  |          len(ch1) | 0
*  |          cap(ch1) | 2
*  |               val | 1
*  |                ok | true
*  --------------------------------------------------------------------------------
*  👇
*  进入case val, ok := <-ch2
*  --------------------------------------------------------------------------------
*  |               key | value
*  --------------------------------------------------------------------------------
*  |          len(ch2) | 0
*  |          cap(ch2) | 0
*  |               val | 1
*  |                ok | true
*  --------------------------------------------------------------------------------
*  👇
*  进入case ch1 <- 1
*  --------------------------------------------------------------------------------
*  |               key | value
*  --------------------------------------------------------------------------------
*  |          len(ch1) | 1
*  |          cap(ch1) | 2
*  --------------------------------------------------------------------------------
*  👇
*  val, ok := <-ch1
*  --------------------------------------------------------------------------------
*  |               key | value
*  --------------------------------------------------------------------------------
*  |          len(ch1) | 0
*  |          cap(ch1) | 2
*  |               val | 1
*  |                ok | true
*  --------------------------------------------------------------------------------
*  👇
*  进入case ch1 <- 1
*  --------------------------------------------------------------------------------
*  |               key | value
*  --------------------------------------------------------------------------------
*  |          len(ch1) | 1
*  |          cap(ch1) | 2
*  --------------------------------------------------------------------------------
*  👇
*  val, ok := <-ch1
*  --------------------------------------------------------------------------------
*  |               key | value
*  --------------------------------------------------------------------------------
*  |          len(ch1) | 0
*  |          cap(ch1) | 2
*  |               val | 1
*  |                ok | true
*  --------------------------------------------------------------------------------
*  👇
*  进入case val, ok := <-ch2
*  --------------------------------------------------------------------------------
*  |               key | value
*  --------------------------------------------------------------------------------
*  |          len(ch2) | 0
*  |          cap(ch2) | 0
*  |               val | 2
*  |                ok | true
*  --------------------------------------------------------------------------------
**************************************************************************************

🏳️‍🌈
**************************************************************************************
*  Test Command: xxx
*  Test Result:
*
**************************************************************************************

🏳️‍🌈
**************************************************************************************
*  Test Command: xxx
*  Test Result:
*
**************************************************************************************

🏳️‍🌈
**************************************************************************************
*  Test Command: xxx
*  Test Result:
*
**************************************************************************************

系列文章

同系列其它文章

参考

Licensed under CC BY-NC-SA 4.0
Built with Hugo
主题 StackJimmy 设计