go语言学习记录 并发
并发
goroutine
函数调用时,在函数前使用 go 关键词即可并发执行
go Add(a,b)
channel
channel是Go语言在语言级别提供的goroutine间的通信方式。**
channel本身在定义后也可以通过channel来传递.
声明
var chanName chan ElementType
var ch chan int
var m map[string] chan bool
定义
ch:= make(chan int)
带缓冲区的channel定义
ch:=make(chan int ,1024)
单向channel变量的声明
var ch1 chan int // ch1是一个正常的channel,不是单向的
var ch2 chan<- float64// ch2是单向channel,只用于写float64数据
var ch3 <-chan int // ch3是单向channel,只用于读取int数据
单向channel初始化
ch4 := make(chan int)
ch5 := <-chan int(ch4) // ch5就是一个单向的读取channel
ch6 := chan<- int(ch4)
写入
ch <- value
向channel写入数据通常会导致程序阻塞,直到有其他goroutine从这个channel中读取数据
读出
value <- ch
如果channel之前没有写入数据,那么从channel中读取数据也会导致程序阻塞,直到channel
中被写入数据为止。
使用range从channel读取数据
for i:=range ch{
fmt.Println("Received:",i)
}
关闭
close(ch)
# 关闭的判断
x,ok = <-ch
select关键词
调用select()函数来监控一系列的文件句柄,一旦其中一个文件句柄发生了IO动作,该select()调用就会被返回。
select {
case <-chan1:
// 如果chan1成功读到数据,则进行该case处理语句
case chan2 <- 1:
// 如果成功向chan2写入数据,则进行该case处理语句
default:
// 如果上面都没有成功,则进入default处理流程
}
超时错误处理
即向channel写数据时发现channel已满,或者从channel试图读取数据时发现channel为空,很可能会导
致整个goroutine锁死。
用select实现达成1秒超时
timeout :=make(chan bool,1)
go func(){
time.Sleep(1e9)
timeout<-true
}()
select{
case <-ch:// 从ch中读取到数据
case <-timeout:// 一直没有从ch中读取到数据,但从timeout中读取到了数据
}
同步锁
sync包 sync.Mutex(单写单读)和sync.RWMutex(单写多读)
对于这两种锁类型,任何一个Lock()或RLock()均需要保证对应有Unlock()或RUnlock()
var l sync.Mutex
func foo() {
l.Lock()
defer l.Unlock()
//...
}