Golang之并发编程二


本文是在上一篇文章的基础上Golang之并发编程一的基础上的续篇,如果有兴趣的话,大家可以先看看上一篇的内容,也希望能给出建议,谢谢。

好了,那接下来继续说Golang的并发编程吧。

多核并行化

在说到Golang的并行化时,先看看并行和并发分别是什么吧。

并发:是在单核cpu的基础上,线程通过时间片或者争夺和让出控制权来实现任务的切换,从而实现多个任务的执行。表面上看就好像多个任务在“同时”进行,而其实在某个时间点上,有且仅有一个任务在执行而已。

并行:是指多核的CPU能让同一个进程内的线程,实现真正意义上的同时运行,在理想情况下是不需要排队的(实际是线程数量往往多余cpu核数)。

在目前的Go编译器中,还不能够发挥多核cpu的优势,虽然通过参加goroutine可以实现多并发,简化并行代码的编写,但这些goroutine都运行在同一个CPU核心上,在一个goroutine得到时间片执行的时候,其他goroutine都会处于等待状态,所以有时候的实际效率可能并没有单线程的高。

所以在目前的Golang版本中,我们可以通过设置环境变量来控制使用多少个CPU核心。

runtime.GOMAXPROCS(16)

通过设置环境变量GOMAXPROCS的cpu核数,我们可以指定使用多少个cpu核心,另外,我们可以通过NumCPU()的方法,来获取当前计算机的cpu核数。

runtime.NumCPU()

golang多核

出让时间片

runtime.Gosched()

当调用这个方法后,该goroutine的会让出自己的时间片让其他goroutine执行。

需要注意的还有一点:当一个goroutine发生阻塞,Go会自动地把与该goroutine处于同一系统线程的其他goroutines转移到另一个系统线程上去,以使这些goroutines不阻塞

同步

虽然使用了channel来作为通信手段,但还是可能避免不了goroutine间的共享数据,所以在golang中,还是提供了资源锁的方案

同步锁

Golang中提供了两种锁类型:sync.Mutex 、sync.RWMutex

Mutex:类似Java中的Lock,一个goroutine获取锁后其他goroutine只能够等待,无论读写操作。

RWMutex:类型Java中的读写锁,读锁占用时,锁写操作,写锁占用时,读写都锁住。

全局唯一性操作

对于全局中只需要运行一次的代码,如初始化操作,golang提供了一个Once类型来保证唯一性操作

var once sync.Once

once.Do(方法名)

调用once.Do时,其他goroutine会被阻塞,知道全局唯一的once.Do()调用结束后才继续

示例:

var a string

var once sync.Once

func setup() {

a = "hello world"

}

func doprint() {

once.Do(setup)

print(a)

}

额外阅读:golang线程同步WaitGroup

认识golang并发

简书:http://www.jianshu.com/p/76c8356a4338


转载于:https://juejin.im/post/5a28f2be51882535c56ccedc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值