Go goroutine

并发性Concurrency

并发概念程序员

Go是并发语言,而非并行语言。并发性是同时处理许多事情的能力。并行性parallelism指能够同时作不少事情。并发

Go中使用Goroutines来实现并发concurently。Goroutines是与其余函数或方法同时运行的函数或方法。异步

goroutines 

Goroutines被认为是轻量级的线程,与线程相比,建立Goroutines成本很小,故Go应用程序能够并发执行数千个Goroutines。async

在线程上优点

  • 与线程相比,Goroutines很是便宜,只是堆栈大小的几个kb,堆栈可根据应用程序的须要增加和收缩。而线程状况下,堆栈大小必须指定而且是固定的。
  • Goroutines被多路复用到较少的OS线程,一个程序中可能只有1个线程与数千个Goroutines,若线程中任何Goroutine都表示等待用户输入,则会建立另外一个OS线程,剩下的Goroutines被转移到新的OS线程。全部这些都由运行时处理,程序员从这些复杂细节中抽象出来,获得一个与并发工做相关的干净的API。
  • 使用Goroutines访问共享内存时,经过设计的通道能够防止竞态条件发生。通道能够被认为时Goroutines通讯的管道。

Go语言协程

定义

不须要在定义时区分是不是异步函数(这点是针对Python3.5引入的async def定义时说明本身是一个协程)函数

调度器在合适的点进行切换(非抢占式的,但切换点也不是任意的点,传统是须要显示写出来,goroutine不须要)spa

可能切换的点:I/O,select  ; channel ;等待锁;函数调用(有时);runtime.Gosched()线程

注意:以上只是参考,不能保证切换,不能保证在其余地方不切换设计

使用-race来检测数据访问冲突3d

使用

任何函数或方法调用前面加上go就能送给调度器运行 ,运行一个新的Goroutine。code

 例子:

例子1:

goroutine.go

输出是:Hello from goroutine 随机打印的值

查看系统究竟起了多少个线程?
top命令查看:CPU 占用率  #TH线程(根据系统核来)

 

Goroutine协程

子程序是协程的一个特例

协程特色:

轻量级”线程”

非抢占式多任务处理,由协程主动交出控制权 

编译器/解释器/虚拟机层面的多任务

多个协程可在一个或多个线程在工做

启动多个Goroutine

例子1

func numbers() {
    for i := 1; i <= 5; i++ {
        time.Sleep(250 * time.Millisecond)
        fmt.Printf("%d ", i)
    }
}
func alphabets() {
    for i := 'a'; i <= 'e'; i++ {
        time.Sleep(400 * time.Millisecond)
        fmt.Printf("%c ", i)
    }
}
func main() {
    go numbers()
    go alphabets()
    time.Sleep(3000 * time.Millisecond)
    fmt.Println("main terminated")
}
输出:1 a 2 3 b 4 c 5 d e main terminated

例子2

 

普通函数与协程对比:doWork作完了才把控制权交给main。

Goroutine规则:

  • 当新Goroutine开始时,Goroutine调用当即返回,且不等待Goroutine执行结束。
  • 当Goroutine调用,而且其任何返回值被忽略以后,go当即执行到下一行代码
  • main的Goroutine应该为其余的Goroutines执行,若main的Goroutine终止了,程序将被终止,其余Goroutine将不会运行。

例子:

func hello() {
    fmt.Println("Hello world goroutine")
}
func main() {
    go hello() //因为main进行Sleep,故go hello()有足够时间在main Goroutine终止以前执行
    time.Sleep(1 * time.Second)
    fmt.Println("main function")
}  //输出是:Hello world goroutine   main function   

 

 

其余语言对协程支持

Go语言原生支持

C++:经过Boost.Coroutine库支持

Java:不支持 (并非彻底不支持,有第三方的)

Python中:Python3.5之前使用yield关键字实现协程,Python3.5加入了async def 对协程原生支持

相关文章
相关标签/搜索