从零开发区块链应用(十)--golang协程使用

2022-02-22 17:58:43 浏览数 (1)

本文作者:杰哥的技术杂货铺[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

0 人点赞