Go语言学习笔记-并发
2017-08-23 14:56
543 查看
并发与并行的区别:
区别:1. 并发:☞逻辑上具备同时处理多个任务的能力,指的是多个任务在同一时间段执行而不是同一时刻
2. 并行:☞物理上同一时刻执行多个任务
goroutine:
goroutine像一个多线程和协程的综合体,运行时会创建多个限制来执行并发任务,且任务单元可调度到其他线程并行执行,最大限度提升执行效率。go关键字
go println("hello world") go funct(s){ println(s) }("hello world")
创建并发任务通过go关键字就可,但是关键字go并非执行并发操作,而是创建一个并发任务单元,放置于系统队列中等待调度器调度执行。等待执行过程中,当前流程不会阻塞,也不会等待该任务启动,存在多个任务时也不会去保证并发任务的执行次序。
每个任务单元相比系统线程栈的MB级别来说小了很多,goroutine定义栈初始只需要2KB。自定义栈采用按需分配的策略,在需要时进行扩容,最大能达到GB规模。
go关键字与defer一样,会因为”延迟执行“而立即计算并复制执行参数,可参考下面例子:
package main import "time" var c int func counter() int { c++ return c } func main() { a := 100 go func(x, y int) { time.Sleep(time.Second) println("go:", x, y) }(a, counter()) a += 100 println("main:", a, counter()) time.Sleep(time.Second * 3) } //输出结果: main: 200 2 go: 100 1
通道
Go内置CSP模型,且鼓励使用CSP通道,以通信来代替内存共享,实现并发安全,不需要开发人员自行维护数据一致和完整性。channel是显式的,收发双方必须都知道数据类型和具体通道。
channel从底层实现上来说是一个队列,同步模式下收发双方必须配对,然后直接复制数据给对方,配对失败则置入等待队列,直到出现适配的另一方
异步模式抢夺的是数据缓冲槽,发送方要求有空草可供写入,接收方要求有缓冲数据可读。
通道除了传递数据之外,通常也被用作事件通知。
func main(){ done := make(chan struct{}) //结束事件 c := make(chan string) //数据传输通道 go func(){ s:=<-c //接受数据 println(s) close(done) //关闭通道,作为结束事件通知 }() c <- "hi!" //发送数据 <-done //阻塞,置入等待 等待数据或事件通知 }
异步模式
可以使用len以及cap函数来获取缓冲区的大小以及缓冲区已缓冲的数量
对于同步模式的channel使用len以及cap返回结果均为0,此不同可用作区分channel是同步还是异步
import "unsafe" func main(){ c := make(chan int,3) //创建一个带3个缓冲槽的异步通道 c<-1 c<-2 println("通道中第一个值: ",<-c) //取出第一个数据 println("通道中第二个值: ",<-c) //取出第二个数据 println("通道中写入值的数量: ",len(c)) println("通道的容积: ",cap(c)) println("通道变量的地址: ",c,"通道的长度: ",unsafe.Sizeof(c)) } //输出 //通道中第一个值: 1 //通道中第二个值: 2 //通道中写入值的数量: 0 //通道的容积: 3 //通道变量的地址: 0xc42006a000 通道的长度: 8
相关文章推荐
- Go语言并发与并行学习笔记(二)
- go语言学习笔记之并发编程
- Go语言并发与并行学习笔记(三)
- Go语言学习笔记---并发
- Go语言并发与并行学习笔记(一)
- Go语言并发与并行学习笔记(一)
- Go语言并发与并行学习笔记(二)
- Go语言并发与并行学习笔记(二)
- Go语言并发与并行学习笔记(三)
- Go语言并发与并行学习笔记(二)
- Go语言并发与并行学习笔记(三)
- Go语言并发与并行学习笔记(二)
- Go语言并发与并行学习笔记(二)
- Go语言并发与并行学习笔记(一)
- Go语言并发与并行学习笔记(一)
- Go语言并发与并行学习笔记(三)
- GO: 语言并发与学习笔记
- GO语言学习笔记3(函数接口并发)
- Go语言并发与并行学习笔记(三)
- Go语言并发与并行学习笔记(一)