0%

Go语言进阶

大部分版本控制系统以文件变更列表的方式存储信息,将它们存储的信息看作是一组基本文件和每个文件随时间逐步累积的差异。Git则把数据看作是对小型文件系统的一系列快照,每当有提交更新或保存项目状态时它就会对当时的全部文件创建一个快照并保存这个快照的索引。

Go语言通道channel

一、基础

二、使用

三、参考


Go语言select语句

一、基础

      在Golang中,select语句用来监听和channel有关的IO操作,当IO操作发生时会触发相应的case动作。select只能应用于 channel的操作,既可以用于channel的数据接收,也可以用于channel的数据发送。如果select的多个分支都满足条件,则会随机的选取其中一个满足条件的分支执行。它和IO机制中的select一样是多路复用通道,有了select语句,可以实现main主线程与goroutine线程之间的互动。如果说channel实现了多个goroutine之前的同步或者通信,那么select则实现了多个channel的同步或者通信,并且select具有阻塞的特性。

  1. 语法格式
    • 候选分支case
    • 默认分支default
1
2
3
4
5
6
7
8
9
10
select {
case <-ch1:
// 如果从ch1信道成功接收数据,则执行该分支代码
case ch2 <- 1:
// 如果成功向ch2信道成功发送数据,则执行该分支代码
case ch3 <- 1:
// 如果成功向ch3信道成功发送数据,则执行该分支代码
default:
// 如果上面都没有成功,则进入 default 分支处理流程
}
  1. 使用注意
    • select语句只能用于信道的读写操作
    • select中的非阻塞case条件是并发执行的,select会选择先操作成功的那个case条件去执行;如果多个同时返回,则随机选择一个执行,此时将无法保证执行顺序
      • 对于阻塞的case语句会直到其中有信道可以操作,如果有多个信道可操作,会随机选择其中一个case执行,无法保证顺序
    • 对于case条件语句中,如果存在信道值为nil的读写操作,则该分支将被忽略,可以理解为从select语句中删除了这个case语句
    • 如果有超时条件语句,判断逻辑为如果在这个时间段内一直没有满足条件的case,则执行这个超时case。如果此段时间内出现了可操作的case,则直接执行这个case。
      • 一般用超时语句代替了default语句
    • 对于空的select{},会引起死锁
    • 对于for中的select{}, 也有可能会引起cpu占用过高的问题

二、使用

  1. 基本用法
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
package main

import (
"fmt"
"time"
)

func main() {
c := make(chan int)
o := make(chan bool)
go func() {
for {
select {
case v:= <-c:
fmt.Println(v)
case <-time.After(10 * time.Second):
fmt.Println("timeout")
o<-true
}
}
}()

go func() {
c<-1
}()

a := <-o
fmt.Println(a)
fmt.Println("main process over")
}

三、参考

  1. 参考一

Go语言nil,你真的懂了吗