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() 
 //... 
}