Go goroutine

使用sync.WaitGroup和go 组合,实现多线程

可增长的栈

    OS线程一般都有固定的栈内存(通常为2MB),一个gorutine的栈在其生命周期开始时只有很小的栈(典型情况下2KB),goroutine的栈不是固定的,它可以按需增大和缩小,goroutine的栈大小限制可以达到1GB,虽然极少会用到这么大。所以在Go语言中,一次创建十万左右的goroutine也是可以的。

goroutine调度

GMP是Go语言运行时(runtime)层面的实现,是go语言自己实现的一套调度系统。区别于操作系统调度OS线程。

    G很好理解,就是goroutine的,里面除了存放本goroutine信息外,还有与所在的P的绑定等信息
    
    M(machine)是Go运行时岁操作系统内核线程的虚拟,M与内核线程一般是一一映射的关系,一个goroutine最终是要放到M上执行的。
    
    P管理着一组goroutine队列,P里面会存储当前goroutine运行的上下文环境(函数指针,堆栈地址,以及地址边界),
    P会对自己管理的goroutine队列做一些调度(比如把占用CPU时间较长的goroutine暂停。运行后续的goroutine等)当自己的队列消费完了就会去全局队列里取,如果全局队列里也消费完了就会去其他P的队列里抢任务。

P 的个数通过runtime.GOMAXPROCS设定(最大256),Go1.5版本后默认为物理核心数

单从线程调度讲,Go语言相比起其他语言的有事在于OS线程是由OS内核来调度的,goroutine则是由Go运行时自己的调度器调度的,这个调度器使用一个称为m:n调度的技术。其一大特点是goroutine的调度是在用户态下完成的,不是耳机内核态与用户之间的频繁切换,包括内存的分配与释放,都是在用户态维护着一块大的内存池,不直接调用系统的malloc函数(除非内存池需要改变),成本比调度OS线程低很多。另一方面充分利用了多核的硬件 资源,近似的把若干goroutine均分在物理线程上,再加上本身goroutine的超轻量,以上种种保证了go调度方面的性能。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值