Go语言的并发,你做对了吗?
并发性是go语言一个非常核心的卖点。这一期我们就来看一下,Go语言的并发性。
[go routines]
首先来看一下goroutines。Go routine是一个轻量级的线程。
启动方式,就用go关键字
go f(x)
。
Go routines跑在同一样的地址空间, 所以在访问共享内存变量的时候一定要注意同步的问题。
[channels]
channels直译过来就是管道,用起来也像管道。你可以通过管道来发送或者传输数据。
运算符是小于号减<-。
ch <- v
上面这个表示发送变量v中的数据到管道 ch。
v:=<- ch
上面这个则表示从管道ch中获取数据并存放给变量v。
小于号相当于箭头,这个箭头的指向就是数据的流向。
创建一个管道的方式用make(chan int).
缺省的,发送和接收动作会等待另一端准备好以后才进行。够语言,这么设计的目的,就是为了防止使用一些显性的锁和条件变量来实现同步处理, 从而可以简化代码的设计。
[buffered channel]
buffered channels 即缓冲管道。在创建管道的时候,输入第2个参数即缓冲的长度来创建一个缓冲管道
make(chan int, 10).
缓冲管道的特点是这样子的:
只有当缓冲满了的时候,发送才会开始。
只有当缓冲有空的时候,接收才会开始。
当缓冲满了还要往里添加的话,就会形成死锁错误。
[close channel]
此外管道还可以被关闭。只有管道的发送方才可以关闭管道, 关闭的方法就是close(ch)。管道关闭以后,就没有值再发出来了。接收者在接收数据的时候可以传入第2个参数来测试管道是否关闭。
v, ok := <-ch
可以用for循环来连续的从一个管道中获取数据。
for i:=range c
关闭管道的主要用途就是为了告诉接收方,没有后续数据再进来了。这样接收方可以关掉接收管道数据的程序。
[select]
Select 和 case用来选择哪一个goroutine可以运行。感觉上这一个跟switch case有点相像。
还可以指定一个缺省的选项,在没有任何指定选项符合条件的情况下可以运行这个缺省选项。
[Mutex]
最后我们来看一下go语言里面的互斥。当我们允许同时只有一个goroutine访问一个变量的时候,我们就需要使用互斥机制。使用互斥,就是调用他的两个方法 lock和unlock。
这里值得一提的是,在一些函数中使用了互斥锁从而获取数据,我们可以用defer来保证释放一个互斥锁,然后再直接返回数据。
以上这些就是go语言里面的并发机制了。
这一期就说这些,希望对大家有所帮助。
这里是丁哥开讲,欢迎关注防止失联。
网友评论