GoLang之并发并行与goroutine的思考

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

2015-04-14 wcdj


GoLang之Concurrency再讨论一文讨论过并发的几个问题,分别如下:

1,goroutine是否并发的问题
2,goroutine非并发安全性问题
3,并发情况下的原子操作问题

本文在上述讨论的基础上,进一步对goroutine的调度机制,以及并发的实现原理进行讨论。


0 goroutine 轻量的调度单位

程序员使用goroutine可以快速地开发一个并发(可能非并行)执行的程序。goroutine是协程(coroutine,轻量级进程,Light Weight Process)的一种实现,Linux POSIX C也提供了coroutine系统调用。协程(轻量级进程),就是在用户空间实现调度,比线程更轻量的执行单元。协程的调度不是抢占式的,这就意味着同一线程内的协程只有主动放弃CPU,调度器才会将另外一个等待的协程调度进来然后执行。goroutine在Go语言的运行时环境(runtime)中实现,在用户空间内被调度于一个或多个线程之间(而非限定在一个线程中)。当一个goroutine调用了某个可能阻塞的标准库函数之后,这个goroutine则会被运行时环境暂停,另一个准备好的goroutine则被调度进来然后开始执行。

原则上,Go语言运行时环境中的调度器与操作系统的调度器并没有太大区别,都是在某个事件发生时,将最小调度单位暂停或启动,但goroutine的调度在用户空间内执行,因此调度速度更快,并且可以支持大量并发的goroutine同时运行。

Go语言是一个完全编译型的语言(静态语言),它的代码被直接编译成本地机器码执行,因此不存在中间的解释器或者虚拟机。要实现goroutine运行时的功能,Go语言是利用运行时环境来完成的。Go的程序在链接时,都会被加入一套运行时环境。这套环境类似于一个静态库,包含来Go语言中规定的一些运行时特性,例如,垃圾回收,goroutine调度等。在Go语言标准库中,在每个可能产生阻塞的函数中,都会最终通知运行时环境中的调度器,让调度器将当前的goroutine暂停,这样的设计可以极大地简化并发(可能非并行)程序的开发。


1 goroutine与丢失的select/poll/epoll等非阻塞调用

在Go语言中,是否提供了类似C语言中select/poll/epoll函数?如何让一个网络连接使用非阻塞I/O?怎么对网络连接进行异步读写?

这几个问题回答是:Go的网络程序不使用异步操作,一切操作都是同步的,每个goroutine处理一个连接。

在Go代码层面,开发者看到的是使用goroutine来进行阻塞式读写,而在Go的内部实现中,则是利用异步操作,通过对goroutine的调度来完成对事件的处理。作为最小的调度单位,goroutine之间是并发(可能非并行)执行的。







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

本文来自:CSDN博客

感谢作者:delphiwcdj

查看原文:GoLang之并发并行与goroutine的思考

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

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