- 1、本文档共7页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
2.7 并发
有⼈把Go⽐作2 1世纪的C语⾔,第⼀是因为Go语⾔设计简单,第⼆,2 1世纪最重要的
就是并⾏程序设计,⽽Go从语⾔ ⾯就⽀持了并⾏。
goroutine
goroutine是Go并⾏设计的核⼼。goroutine说到底其实就是线程,但是它⽐线程更⼩,
⼗⼏个goroutine可能体现在底 就是五六个线程,Go语⾔内部帮你实现了这些
goroutine之间的内存共享。执⾏goroutine只需极少的栈内存(⼤概是4~5KB) ,当然会根
据相应的数据伸缩。也正因为如此,可同时运⾏成千上万个并发任务。goroutine⽐
thread更易⽤、更⾼效、更轻便。
goroutine是通过Go的runtime管理的⼀个线程管理器。goroutine通过go关键字实现了,
其实就是⼀个普通的函数。
go hello(a, b, c)
通过关键字go就启动了⼀个goroutine 。我们来看⼀个例⼦
package main
import (
fmt
runtime
)
func say(s string) {
for i := 0; i 5; i {
runtime.Gosched()
fmt.Println(s)
}
}
func main() {
go say(world) //开⼀个新的Goroutines执⾏
say(hello) //当前Goroutines执⾏
}
// 以上程序执⾏后将输出:
// hello
// world
// hello
// world
// hello
// world
// hello
// world
// hello
我们可以看到go关键字很⽅便的就实现了并发编程。 上⾯的多个goroutine运⾏在同⼀
个进程⾥⾯,共享内存数据,不过设计上我们要遵循:不要通过共享来通信,⽽要通
过通信来共享。
runtime .Gosched()表⽰让CPU把时间⽚让给别⼈,下次某个时候继续恢复
执⾏该goroutine 。
默认情况下,调度器仅使⽤单线程,也就是说只实现了并发。想要发挥
多核处理器的并⾏,需要在我们的程序中显式调⽤
runtime .GO AXPROCS(n) 告诉调度器同时使⽤多个线程。
GO AXPROCS 设置了同时运⾏逻辑代码的系统线程的最⼤数量,并返
回之前的设置。如果n 1,不会改变当前设置。以后Go的新版本中调度
得到改进后,这将被移除。这⾥有⼀篇Rob介绍的关于并发和并⾏的⽂
章:http://concur .rspace .googlecode .com/hg/talk/concur .html#landing-slide
channels
goroutine运⾏在相同的地址空间,因此访问共享内存必须做好同步。那么goroutine之
间如何进⾏数据的通信呢,Go提供了⼀个很好的通信机制channel 。channel可以与
Unix shell 中的双向管道做类⽐:可以通过它发送或者接收值。这些值只能是特定的
类型:channel类型。定义⼀个channel时,也需要定义发送到channel的值的类型。注
意,必须使⽤make 创建channel :
ci := make(chan int)
cs := make(chan string)
cf := make(chan interface{})
channel通过操作符-来接收和发送数据
ch - v // 发送v到channel ch.
v := -ch // 从ch中接收数据,并赋值 v
我们把这些应⽤到我们的例⼦中来:
package main
import fmt
func sum(a []int, c chan int) {
total := 0
for _, v := range a {
total = v
}
c - total // send total to c
}
func main() {
a := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(a[:len(a)/2], c)
go sum(a
文档评论(0)