Go并发和并行

1、基本概念

并发:并发意味着程序在单位时间内是同时运行的。
并行:并行意味着程序在任意时刻都是同时运行的;

2、goroutine 特性:(go func ();)

(1)go 的执行是非阻塞的,不会等待。
(2)go 后面的函数的返回值会被忽略。
(3)调度器不能保证 goroutin 的执行次序。
(4)没有父子 goroutin 的概念,所有的 goroutin 是平等地被调度和执行的。
(5)Go 程序在执行时会单独为 main 函数 goroutin ,遇到其他go关键字时再去创建其他的 goroutine。
(6)Go 没有暴露 goroutine id 给用户,所以不能在 goroutine 里面显式地操作另一个goroutine 不过 runtime 包提供了一些函数访问和设置 goroutin 的相关信息。

3、goroutine相关函数

(1)func GOMAXPROCS(n int)int 是用来设置或查询可以井发执行的 goroutine 数目,n大于1表示设置 GOMAXPROCS,否则表示查询当前的 MAXPRO值。
(2)func Goexit()是结束当前goroutine的运行,Goexit 在结束当前 goroutine 运行之前会调用当前 goroutine 已经注册的 defer,Goexit 并不会产生 panic ,所以该 goroutine defer 里面的 recover调用都返回 nil。
(3)func Gosched())是放弃当前调度执行机会,将当前 goroutine 放到队列中等待下次被调度。

4、chan(通道:通道是 routine 之间通信和同步的重要组件。Go的哲学是“不要通过共享内存来通信,而是通过通信来共享内存”,通道是 Go 通过通信来共享内存的载体。)

通道分类:有缓冲通道(有缓冲的通道的 len 代表没有被读取的元素数, cap 代表整个通道的容量)和无缓冲通道(len和cap都是0)。
使用:无缓冲的通道既可以用于通信,也可以用于两个 goroutine 的同步,有缓冲的通道主要用于通信。
操作不同状态的 chan 会引发以下3种行为:
	(1)panic
			i. 向已经关闭的通道写数据会导致 panic。最佳实践是由写入者关闭通道,能最大程度地避免向已经关闭的通道写数据而导致的 panic。
			ii. 重复关闭的通道会导致 panic。
	(2)阻塞
			i. 向未初始化的通道写数据或读数据都会导致当前 goroutine 的永久阻塞。
			ii. 向缓冲区己满的通道写入数据会导致 goroutine 塞。
			iii. 通道中没有数据,读取该通道会导致 goroutine 塞。
	(3)非阻塞
			i. 读取己经关闭的通道不会引发阻塞,而是立即返回通道元素类型的零值,可以使用comrna , ok 语法判断通道是否己经关闭。
			ii. 向有缓冲且没有满的通道读或写不会引发 塞。

5、扇入( Fan in )和扇出( Fan out )

扇入是指将多路通道聚合到一条通道中处理 Go 语言最简单的扇入就是使用 ec 聚合多条通道服务;扇出是指将一条通道发散到多条通道中处理,在 Go 语言里面具体实现就是使用 关键字启动多个 oroutine 并发处理。

6、通知退出机制

关 select 监听的某 通道能使 se ec 感知这种通知,然后进行相应 处理 这就是所谓的退出通知机制( clo se channel to bro dc as )

7、context包

设计目的:跟踪 goroutin 调用树,并在这些 gouroutine 调用树中传递通知和元数据
(1)退出通知机制一一通知可以传递给整个 goroutine 调用树上的每一个 goroutine
(2)传递数据 ——数据可以传递给整个 goroutine 调用树上的每个goroutine
使用 Contex 包的一般流程如下:
(1)创建 Context 根对象。
(2)包装上一步 Context ,使其具有特定功能。这些包装 数是 context package 的核心,几乎所有的封装都是从包装函数开始的,原因很简单,使用 context 就是使用其退出通知广播功能。
(3)将上一步创建的对象作为实参传递给后续启动的并发函数(通常作为函数的第一个参数),每个并发函数内部可以继续使用包装函数对传递来的 Context对象进行包装,添加自己所需要的功能。
(4)顶端 goroutine 在超时后调用 cancel 退出通知函数,通知后端的所有 goroutin 释放资源。
(5)后端 goroutine 通过 select 监昕 Context.Done()返回的 chan 及时响应前端 goroutine的退出通知,一般停止本次处理,释放所占用的资源。

8、在context 中传递数据的坏处

(1)传递的都是 interface {}类型的值,编译器不能进行严格的类型校验。
(2)从 interface {}到具体类型需要使用类型断言和接口查闹,有一定的运行期开销和性能
损失。
(3)值在传递过程中有可能被后续的服务覆盖,且不易被发现。
(4)传递信息不简明,较晦涩;不能通过代码或文档 眼看到传递的是什么,不利于后续维护。

9、context 应该传递什么数据

(1)日志信息。
(2)调试信息。
(3)不影响业务主逻辑的可选数据。
context 包提供的核心的功能是多 goroutine 之间的退出通知机制,传递数据只是 个辅助功能,应谨慎使用 context 传递数据。

10、Go并发模型
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值