不知道你有没有注意到,这段代码如果我跑在两个goroutines里面的话:

  

package main

import (
"fmt"
) func loop(done chan bool) {
for i := 0; i < 10; i++ {
fmt.Print(i)
}
done <- true
} func main() {
done := make(chan bool)
go loop(done)
go loop(done) <-done
<-done }

他的输出结果: 01234567890123456789

go不是会新起一个goroutine来运行loop函数吗。以前我们用线程去做类似任务的时候,系统的线程会抢占式地输出, 表现出来的是乱序地输出。而goroutine为什么是这样输出的呢?

关于并行和并发,下面这张图说明:

  • 两个队列,一个Coffee机器,那是并发
  • 两个队列,两个Coffee机器,那是并行

默认地, Go所有的goroutines只能在一个线程里跑 。

如果当前goroutine不发生阻塞,它是不会让出CPU给其他goroutine的, 所以上面的例子的输出会是一个一个goroutine进行的

真正的并行

为了达到真正的并行,runtime.GOMAXPROCS(2)试试看

package main

import (
"fmt"
"runtime"
) func loop(done chan bool) {
for i := 0; i < 100; i++ {
fmt.Printf("%d ", i)
}
done <- true
} func main() {
runtime.GOMAXPROCS(2)
done := make(chan bool)
go loop(done)
go loop(done) <-done
<-done }

这下会看到两个goroutine会抢占式地输出数据了。我们还可以这样显式地让出CPU时间:

package main

import (
"fmt"
"runtime"
) func loop(done chan bool) {
for i := 0; i < 100; i++ {
fmt.Printf("%d ", i)
runtime.Gosched() //// 显式地让出CPU时间给其他goroutine
}
done <- true
} func main() {
// runtime.GOMAXPROCS(2)
done := make(chan bool)
go loop(done)
go loop(done) <-done
<-done }

总结

我们从例子中可以看到,默认的, 所有goroutine会在一个原生线程里跑

在同一个原生线程里,如果当前goroutine不发生阻塞,它是不会让出CPU时间给其他同线程的goroutines的,这是Go运行时对goroutine的调度,我们也可以使用runtime包来手工调度。

当一个goroutine发生阻塞,Go会自动地把与该goroutine处于同一系统线程的其他goroutines转移到另一个系统线程上去,以使这些goroutines不阻塞

Go语言的并发和并行的更多相关文章

  1. Go语言并发与并行学习笔记(二)

    转:http://blog.csdn.net/kjfcpua/article/details/18265461 Go语言的并发和并行 不知道你有没有注意到一个现象,还是这段代码,如果我跑在两个goro ...

  2. go并发和并行

    Go语言的并发和并行 不知道你有没有注意到一个现象,还是这段代码,如果我跑在两个goroutines里面的话: var quit chan int = make(chan int) func loop ...

  3. Go语言并发与并行学习笔记(三)

    转:http://blog.csdn.net/kjfcpua/article/details/18265475 Go语言并发的设计模式和应用场景 以下设计模式和应用场景来自Google IO上的关于G ...

  4. geotrellis使用(六)Scala并发(并行)编程

    本文主要讲解Scala的并发(并行)编程,那么为什么题目概称geotrellis使用(六)呢,主要因为本系列讲解如何使用Geotrellis,具体前几篇博文已经介绍过了.我觉得干任何一件事情基础很重要 ...

  5. Python 多线程教程:并发与并行

    转载于: https://my.oschina.net/leejun2005/blog/398826 在批评Python的讨论中,常常说起Python多线程是多么的难用.还有人对 global int ...

  6. Python并发与并行的新手指南

    点这里 在批评Python的讨论中,常常说起Python多线程是多么的难用.还有人对 global interpreter lock(也被亲切的称为“GIL”)指指点点,说它阻碍了Python的多线程 ...

  7. 《Go in action》读后记录:Go的并发与并行

    本文的主要内容是: 了解goroutine,使用它来运行程序 了解Go是如何检测并修正竞争状态的(解决资源互斥访问的方式) 了解并使用通道chan来同步goroutine 一.使用goroutine来 ...

  8. [Go] 并发和并行的区别

    并发和并行的区别:1.并行是让不同的代码片段同时在不同的物理机器上运行,并行的关键是在不同的物理机器上同时运行 2.并发是同时管理很多事情,比如在一个物理机器上进行不停的调度,有些事情可能只做了一半就 ...

  9. Go语言的并发

    一.Go语言中Goroutine的基本原理 Go语言里的并发指的是能让某个函数独立于其他函数运行的能力. Go语言的goroutine是一个独立的工作单元, Go 语言的并发同步模型来自一个叫作通信顺 ...

随机推荐

  1. Python3.5在Windows7环境下Scrapy库的安装

    Python3.5在Windows7环境下Scrapy库的安装 忙活了一下午,总算是把Scrapy库给装完了,记下来给需要帮助的人 首先安装的环境:Windows7 64位 Python的版本是:3. ...

  2. Python学习之路4 - 文件操作&编码转换

    文件操作 文件操作大概分三步: 把文件打开. 操作文件. 把文件关上. 打开文件 打开文件用open()函数,打开成功后返回一个资源,具体语法如下. open(要打开的文件,打开方式,打开文件的格式, ...

  3. c++ new 堆 栈

    根据32位的Windows系统默认有2GB的用户空间,则不能new超过2GB的,执行下列代码: ***]; 会出现下面的错误 error C2148: 数组的总大小不得超过 0x7fffffff 字节 ...

  4. c运行时库,c标准库,Windows系统api的关系

    原文地址:http://blog.csdn.net/seastars_sh/article/details/8233324 C运行库和C标准库的关系 C标准库,顾名思义既然是标准,就是由标准组织制定的 ...

  5. 苹果ATS特性服务器配置指南 HTTPS 安卓可以用 IOS 报错。

    解决方案:https://www.qcloud.com/document/product/400/6973 ATS检测:https://www.qcloud.com/product/ssl#userD ...

  6. springBoot配置分析(属性和结构化)

    使用idea自带插件创建项目 一直下一步到完成 application.properties local.ip.addr = 192.168.2.110 redis.host = 192.168.3. ...

  7. 【刷题】BZOJ 3546 [ONTAK2010]Life of the Party

    Description 一个舞会有N个男孩(编号为1..N)和M个女孩(编号为1..M),一对男女能够组成一对跳舞当且仅当他们两个人互相认识. 我们把一种人定义成这个舞会的life:当且仅当如果他(她 ...

  8. BZOJ1492: [NOI2007]货币兑换Cash 【dp + CDQ分治】

    1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 5391  Solved: 2181 [Submit][S ...

  9. BZOJ1834 [ZJOI2010]network 网络扩容 【最大流,费用流】

    1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec  Memory Limit: 64 MB Submit: 3394  Solved: 1774 [Subm ...

  10. 20165218 2017-2018-1 《Java程序设计》第四周学习总结

    20165218 2017-2018-1 <Java程序设计>第四周学习总结 教材学习内容总结 第五章 子类与继承 子类与父类 通过关键字extands定义子类 class 子类 exta ...