golang协程实现探讨

盈朔 · · 684 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

问题一:介绍一下协程的运行时runtime,以及他跟协程有什么关系,为什么需要先介绍它?

答:你要能从根本上了解一下这个语言的实现,才能更好的知道协程是怎么实现的。首先它是一个二进制的应用程序,这就和c#,python.lua语言有点不同,他们只是编译成一种中间代码,然后需要一个运行的程序去读取翻译他们,这个运行的程序一般理解为运行时。golang把和操作系统的系统调用、协程实现、统一管理(调度器)、gm。做了一个统一的封装,叫做运行时,我们编译golang项目的时候会先编程合成文件,然后在链接的时候,他会链接golang已经封装好的运行时文件。最后合成应用程序。

问题二:介绍一下golang的大体设计想法?

答:最早golang是创建了几个线程,然后在全局区域创建了一个队列,然后处理单元会放入这个队列中,一个线程采用加锁的方式去访问这个队列,但是这个频繁的加锁和解锁导致性能下降,所以后来引入管理器,管理器里面会有一个私用的队列,然后一个线程去绑定一管理。除此之外全局区域仍然会有一个对应的全局队列。这就是golang大体上的设计模型。

问题三:看起来协程的设计也不复杂,但是使用起来感觉很牛逼,不会这么简单吧?

答:在这个golang的协程设计框架之上,golang还封装了调度器的东西,这个东西不是谁都能实现的,调度器里面还有一个监督处理单元(gorountine)状态的东西,调度器会根据gorountine的状态,去判断是否需要去创建新的线程,是否需要把一个管理器内的处理单元是否需要转移到其他管理器上面,以及系统调用。

问题四:能介绍一下channel么?以及如何实现一下gorountine发完消息堵塞,然后又继续运行?

答:channel里面主要有4部分:

第1部分就是缓存和缓存游标。

第2部分发gorountine队列,

第3部分接收gorountine队列,

第4部分锁。

是不看完这些感觉channel也很好实现么,那你就错了,在具体实现上并不是,channel在实现的时候为了实现gorountine在读写channel的时候堵塞和继续运行的效果,会调用golang的运行时(runtime),和golang调度器,会暂时 把当前运行的gorountine从调度器中移除。这个才是关键。

问题五:你觉得如果要实现golang,最难的地方是什么?

答:golang中最难的地方是运行时(runtine)和调度器。我个人这样认为的。

问题六:你已经写一段时间golang了,你遇到过最棘手的问题是什么?什么原因?如何解决?

答:我遇到过golang最棘手的问题是程序卡死,无响应了。原因是我创建了多个gorountine。然后在gorountine中写了for{} ,就是死循环,别以为是bug。这是我故意,需要

For{

    Select{

    }

}

我的需求需要这样去做,那么为什么这样会出死循环尼,就是golang的调度器里面有监听所有gorountine的线程,当有gorountine运行的时间比较长的时候,gorountine就会被移到全局队列中,然后当下面的管理器(p)运行完自己的gorountine的时候,就在一次重全局队列中拿,然后一个管理器对应一个线程,当所用的线程都有死循环的gorountine的时候,golang程序就卡死了。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:盈朔

查看原文:golang协程实现探讨

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

684 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传