本文作者:杰哥的技术杂货铺[1]
一、什么是并发
1.1 并发定义
为了更有意思的解释这个概念,我借用知乎上的一个回答:你吃饭吃到一半,电话来了,你一直到吃完了以后才去接,这就说明你不支持并发也不支持并行。你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发。你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并行。并发的关键是你有处理多个任务的能力,不一定要同时。并行的关键是你有同时处理多个任务的能力。对应到 CPU 上,如果是多核它就有同时执行的能力,即有并行的能力。对于 Go 语言,它自行安排了我们的代码合适并发合适并行。
1.2 并发的好处
二、什么是协程
2.1 协程定义
协程是一种用户态的轻量级线程,又称微线程。
在 go 程序中,go 语言在运行时会自动的创建和销毁系统级的线程。系统级线程指的是操作系统提供的线程。
那么对应的用户级线程,指的是架设在系统级线程之上的,用户级线程的创建、销毁、调度、状态变更,都需要靠我们的程序自己去实现和处理。
与线程相比,创建 gotoutine 的成本很小,他就是一段代码,一个函数入口
2.2 协程的优点
协程的创建和销毁不需要通过操作系统去做,因此,是没有线程切换的开销,所以速度会很快,可以提高任务并发性
三、golang 协程实践
协程 类似于一个线程,但是由 Go 而不是操作系统预定。在 协程 中运行的代码可以与其他代码同时运行。我们来看一个
代码语言:javascript复制package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("start")
go process()
time.Sleep(time.Millisecond * 10) // this is bad, don't do this!
fmt.Println("done")
}
func process() {
fmt.Println("processing")
}
这里有一些有趣的事情, 但最重要的是我们如何开始一个 协程 。我们只需使用 go 关键字,然后使用我们想要执行的函数。如果我们只想运行一部分代码, 如上所述, 我们可以使用匿名函数。需要注意的是,匿名函数不只是可以在 协程 中使用,其他地方也可以。
代码语言:javascript复制go func() {
fmt.Println("processing")
}()
协程 易于创建且开销很小。最终多个 协程 将会在同一个底层的操作系统线程上运行。这通常也称为 M:N 线程模型,因为我们有 M 个应用线程( 协程 )运行在 N 个操作系统线程上。结果就是,一个 协程 的开销和系统线程比起来相对很低(几 KB)。在现代的硬件上,有可能拥有数百万个 协程 。
此外,这里还隐藏了映射和调度的复杂性。我们只需要说 这段代码需要同时并发执行 然后让 Go 自己去实现它。
如果我们回到我们的例子中,你将会注意到我们使用 Sleep 让程序等了几毫秒。这是因为主进程在退出前 协程 才会有机会去执行(主进程在退出前不会等待全部 协程 执行完毕)。要解决这个问题,我们需要协调我们的代码。
本系列文章:
从零开发区块链应用(一)--golang 配置文件管理工具 viper[2]
从零开发区块链应用(二)--mysql 安装及数据库表的安装创建[3]
从零开发区块链应用(三)--mysql 初始化及 gorm 框架使用[4]
从零开发区块链应用(四)--自定义业务错误信息[5]
从零开发区块链应用(五)--golang 网络请求[6]
从零开发区块链应用(六)--gin 框架使用[7]
从零开发区块链应用(七)--gin 框架参数获取[8]
从零开发区块链应用(八)--结构体初识[9]
从零开发区块链应用(九)--区块链结构体创建[10]
从零开发区块链应用(十)--golang 协程使用[11]
从零开发区块链应用(十一)--以太坊地址生成[12]
参考资料
[1]
杰哥的技术杂货铺: https://learnblockchain.cn/people/3835
[2]
从零开发区块链应用(一)--golang配置文件管理工具viper: https://learnblockchain.cn/article/3446
[3]
从零开发区块链应用(二)--mysql安装及数据库表的安装创建: https://learnblockchain.cn/article/3447
[4]
从零开发区块链应用(三)--mysql初始化及gorm框架使用: https://learnblockchain.cn/article/3448
[5]
从零开发区块链应用(四)--自定义业务错误信息: https://learnblockchain.cn/article/3449
[6]
从零开发区块链应用(五)--golang网络请求: https://learnblockchain.cn/article/3457
[7]
从零开发区块链应用(六)--gin框架使用: https://learnblockchain.cn/article/3480
[8]
从零开发区块链应用(七)--gin框架参数获取: https://learnblockchain.cn/article/3481
[9]
从零开发区块链应用(八)--结构体初识: https://learnblockchain.cn/article/3482
[10]
从零开发区块链应用(九)--区块链结构体创建: https://learnblockchain.cn/article/3483
[11]
从零开发区块链应用(十)--golang协程使用: https://learnblockchain.cn/article/3484
[12]
从零开发区块链应用(十一)--以太坊地址生成: https://learnblockchain.cn/article/3485