|
作者:dcguo,腾讯CSIG电子签开放平台中心分享Golang并发基础库,扩展以及三方库的一些常见问题、使用介绍和技巧,以及对一些并发库的选择和优化探讨。go原生/扩展库提倡的原则不要通过共享内存进行通信;相反,通过通信来共享内存。Goroutinegoroutine并发模型调度器主要结构主要调度器结构是M,P,GM,内核级别线程,goroutine基于M之上,代表执行者,底层线程,物理线程P,处理器,用来执行goroutine,因此维护了一个goroutine队列,里面存储了所有要执行的goroutine,将等待执行的G与M对接,它的数目也代表了真正的并发度(即有多少个goroutine可以同时进行);G,goroutine实现的核心结构,相当于轻量级线程,里面包含了goroutine需要的栈,程序计数器,以及所在M的信息P的数量由环境变量中的GOMAXPROCS决定,通常来说和核心数对应。映射关系用户空间线程和内核空间线程映射关系有如下三种:N:11:1M:N调度图关系如图,灰色的G则是暂时还未运行的,处于就绪态,等待被调度,这个队列被P维护注:简单调度图如上,有关于P再多个M中切换,公共goroutine队列,M从线程缓存中创建等步骤没有体现,复杂过程可以参考文章简单了解goroutine如何实现。goroutine使用demo1go list.Sort()demo2func Announce(message string, delay time.Duration) { go func() { time.Sleep(delay) fmt.println(message) }()}channelchannel特性创建// 创建 channela := make(chan int)b := make(chan int, 10)// 单向 channelc := make(chan0; i++ { B->CA调用B,B调用C,当A不依赖B请求C得结果时,B请求C之后直接返回A,那么A,B间context被cancel,而C得context也是继承于前面,C请求直接挂掉,只需要重新搞个context向下传就好,记得带上reqId,logId等必要信息。并行某些计算可以再CPU之间并行化,如果计算可以被划分为不同的可独立执行的部分,那么他就是可并行化的,任务可以通过一个channel发送结束信号。假如我们可以再数组上进行一个比较耗时的操作,操作的值在每个数据上独立,如下:type vector []float64func (v vector) DoSome(i, n int, u Vector, c chan int) { for ; i
|
|