Go中的Channel通讯

runtime包介绍

(图片来自Go语言中文网)
图片来自GO语言中文网

一些较为重要的函数介绍
func NumCPU() int

 
 
  • 1

使用NumCPU方法能够获得一个本地机器的逻辑CPU个数的int类型数值

func GOMAXPROCS(n int)  int

 
 
  • 1

GOMAXPROCS设置可同时执行的最大CPU数,并返回先前的设置。 若 n < 1,它就不会更改当前设置。本地机器的逻辑CPU数可通过 NumCPU 查询。本函数在调度程序优化后会去掉。
一般来说,在go1.8版本之后,系统会默认使用全部逻辑CPU进行并行操作。而在go1.8之前的版本,则需要自己设置(即使用GOMAXPROCS)。有的时候设计者需要保留一些CPU的功能占用,也会自主设定GOMAXPROCS比最大可用CPU数量少一些。
拓展完毕。接下来进入正题


那么不同的Goroutine之间如何通讯呢?有两种方式:
1、全局变量互斥锁
2、管道Channel

在Go语言中倡导:“不要以共享内存的方式来通信,相反,要通过通信来共享内存。”
首先看一下传统的并发形式:

多线程共享内存,这也是Java、C#或者C++等语言中的多线程开发的常规方法,其实golang语言也支持这种传统模式。

另外一种是Go语言特有的:CSP(Communicating Sequential Processes)并发模型。不同于传统的多线程通过共享内存来通信,CSP讲究的是“以通信的方式来共享内存”。

在讲同步通信之前先来看一下最简单基础的锁机制

锁机制

锁甚至可以直接理解为同步(Synchronization)。首先了解一下为什么会需要锁机制。在读取和写入这两种方法中,读取是不需要锁的,因为可以多个线程同时读取。而写就不可以,需要加入锁(像最简单的互斥锁Mutex),防止其他的线程进行干扰。
一般情况有两种锁,一种是互斥锁, 一种是读写锁,其中加了互斥锁的程序性能比读写锁的性能要低200倍
(图片来自Go语言中文网)
在这里插入图片描述
举个关于互斥锁的?:有一个电影,多个人同时去看,不会出现问题(读取的线程)。但是拍电影的时候,一个场景只能由一个摄像机去拍摄(纯3D立体除外。。。),不能多个同时拍一个画面,剪切出来的也是一个摄像机拍出来的(写入的线程)。
再举一个关于读写锁的?:在大学课堂都经历过,教室里面有黑板,全班的同学都可以看黑板上面老师的板书(读), 但是能够写黑板的只有老师一个人(写)。那么如果有两个老师同时想要写黑板的话,就会造成同学们无法确定该看(读)谁写的文字。因此其中一个老师在黑板上书写文字内容的时候, 需要把这一过程上锁,一旦上了读写锁,那么第二个老师只能等待第一个老师书写完毕才可以进行书写。

锁主要是为了防止线程之间对于资源的干扰,当一个线程对本身的操作加锁之后(Lock),那么别的线程就无法访问与其相关的内容,这样不会出现干扰,像写入异常等。最经典的就是Data race,资源争夺。
锁需要引入“sync”标准包
(图片来自Go语言中文网)
在这里插入图片描述
由图片对于sync标准包的介绍可以看到,锁一般适用于低水平程序线程,高水平同步应该使用channel通信更好。接下来进入Go的一大特色,channel管道。


管道Channel

先说一下为什么会需要channel。在前面说可以使用加锁来同步解决goroutine的通信,但是并不完美。因为主线程如果退出的话会导致未完成工作的goroutine协程提前退出,这样会出现各种各样的问题。
在我最开始的时候想到通过sleep来获取更多时间,使协程能够运行完毕。但是如果需要运算的内容特别庞大,那么时间就不好把控。sleep时间多了会加长等待切浪费资源,少了,主线程退出goroutine退出销毁程序异常。
而且还存在一个问题,比较不容易判断出在哪里需要增加锁(lock),哪里需要解除锁(unlock)。因此,go设计了一个新的通讯机制Channel。

下面基本介绍一下channel
1、 channel的本质就是一个数据结构-队列
2、channel遵循队列的读取顺序,先进先出(FIFO:first in first out)。
3、channel的线程是很安全的!它是由编译器在底层维护的。多个goroutine对同一个channel进行操作,都可以稳定安全的运行,不出现资源竞争问题。channel本身是不需要使用锁的,但是从源码可以看出,channel本身是有锁,使它本身的机制而来(底层代码实现),我们调用的时候并不需要再去添加或解除锁。
4、channel本身是有数据类型的。string类型的channel只能存放string类型的数据。一般我们都设置为interface{}类型,这样取的时候可以不用进行类型断言去取,免除了一些不必要的麻烦。


未完待续…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值