共享变量
协程之间的通信只能够通过通道。但是我们习惯于共享变量,而且很多时候使用共享变量能让代码更简洁。比如一个Server有两个状态开和关。其他仅仅希望获取或改变其状态,那又该如何做呢。可以将这个变量至于0通道中,并使用一个协程来维护。
下面的例子描述如何用这个方式,实现一个共享变量。
//共享变量有一个读通道和一个写通道组成
typesharded_var struct {
reader chan int
writer chan int
}
//共享变量维护协程
funcsharded_var_whachdog(v sharded_var) {
go func() {
//初始值
var value int = 0
for {
//监听读写通道,完成服务
select {
case value =<-v.writer:
case v.reader <-value:
}
}
}()
}
funcmain() {
//初始化,并开始维护协程
v := sharded_var{make(chan int),make(chan int)}
sharded_var_whachdog(v)
//读取初始值
fmt.Println(<-v.reader)
//写入一个值
v.writer <- 1
//读取新写入的值
fmt.Println(<-v.reader)
}
这样,就可以在协程和通道的基础上实现一个协程安全的共享变量了。定义一个写通道,需要更新变量的时候,往里写新的值。再定义一个读通道,需要读的时候,从里面读。通过一个单独的协程来维护这两个通道。保证数据的一致性。
一般来说,协程之间不推荐使用共享变量来交互,但是按照这个办法,在一些场合,使用共享变量也是可取的。很多平台上有较为原生的共享变量支持,到底用那种 实现比较好,就见仁见智了。另外利用协程和通道,可以还实现各种常见的并发数据结构,如锁等等,就不一一赘述。