Go语言中goroutine的使用

 更新时间:2023年06月28日 11:24:46   作者:码一行  
本文主要介绍了Go语言中goroutine的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、什么是 Goroutine ?

java/c++中我们要实现并发编程的时候,我们通常需要自己维护一个线程池,并且需要自己去包装一个又一个的任务,同时需要自己去调度线程执行任务并维护上下文切换,这一切通常会耗费程序员大量的心智。那么能不能有一种机制,程序员只需要定义很多个任务,让系统去帮助我们把这些任务分配到CPU上实现并发执行呢?

Go语言中的goroutine就是这样一种机制,goroutine的概念类似于线程,但 goroutine是由Go的运行时(runtime)调度和管理的。Go程序会智能地将 goroutine 中的任务合理地分配给每个CPUGo语言之所以被称为现代化的编程语言,就是因为它在语言层面已经内置了调度和上下文切换的机制。

Go语言编程中你不需要去自己写进程、线程、协程,你的技能包里只有一个技能–goroutine,当你需要让某个任务并发执行的时候,你只需要把这个任务包装成一个函数,开启一个goroutine去执行这个函数就可以了,就是这么简单粗暴。

二、使用 Goroutine

Go语言中使用goroutine非常简单,只需要在调用函数的时候在前面加上go关键字,就可以为一个函数创建一个goroutine

一个goroutine必定对应一个函数,可以创建多个goroutine去执行相同的函数。

单个 goroutine

package main
import "fmt"
func hello() {
    fmt.Println("Hello Goroutine!")
}
func main() {
    go hello()
    fmt.Println("main goroutine done!")
}

执行这段程序:

main goroutine done! 

那么问题来了:为什么 Hello Goroutine! 没有输出呢?

在程序启动时,Go程序就会为main()函数创建一个默认的goroutine

main()函数返回的时候该goroutine就结束了,所以在main()函数中启动的goroutine会一同结束,main函数所在的goroutine就像是权利的游戏中的夜王,其他的goroutine都是异鬼,夜王一死它转化的那些异鬼也就全部GG了。

所以咱们要想办法让main函数等一等hello函数,最简单粗暴的方式就是time.Sleep了。

示例:

package main
import "fmt"
func hello() {
    fmt.Println("Hello Goroutine!")
}
func main() {
    go hello()
    fmt.Println("main goroutine done!")
    time.Sleep(time.Second) // 等待1秒
}

执行这段程序:

Hello Goroutine!
main goroutine done!

多个 goroutine

package main
import "fmt"
func hello() {
    fmt.Println("Hello Goroutine!")
}
func word() {
    fmt.Println("Word Goroutine!")
}
func main() {
    go hello()
    go word()
    fmt.Println("main goroutine done!")
    time.Sleep(2 * time.Second) // 等待2秒
}

执行这段程序:

Hello Goroutine!
Word Goroutine!
main goroutine done!

开启多个 goroutine 只需要再使用一次go关键字就可以了。

同样的,咱们为了让它能够完整输出,使用 time.Sleepmain函数等待 goroutine 执行完成。

sync.WaitGroup 的使用

上面咱们讲了如何开启goroutine,为了goroutine正常输出,增加了 time.Sleep 等待。

但在我们实际项目开发中,生硬的使用time.Sleep肯定是不合适的。那我们应该如何才能正确优雅的让 main 函数等待 goroutine 执行完之后再执行呢?

go语言提供了一个 sync.WaitGroup 的一个计数器的功能。可以用来优雅的实现 goroutine 的正常执行和 main 函数的等待。

示例:

package main 
import (
    "fmt"
    "sync"
)
var wg sync.WaitGroup
func hello(){
    defer wg.done()  // 计数器 - 1
    fmt.Println("Hello Goroutine!")
}
func main(){
    wg.Add(1)  // 计数器 + 1
    go hello()
    wg.wait()  // 阻塞直到计数器变为0
    fmt.Println("main goroutine done!")
}

执行这段程序:

Hello Goroutine!
main goroutine done!

方法名功能
(wg * WaitGroup) Add(delta int)计数器+delta
(wg *WaitGroup) Done()计数器-1
(wg *WaitGroup) Wait()阻塞直到计数器变为0

sync.WaitGroup内部维护着一个计数器,计数器的值可以增加和减少。例如当我们启动了 N 个并发任务时,就将计数器值增加N。每个任务完成时通过调用Done()方法将计数器减1。通过调用Wait()来等待并发任务执行完,当计数器值为0时,表示所有并发任务已经完成。

在实际项目中使用sync.WaitGroup 可以更好的、更优雅的控制goroutine

三. 结束语

到此这篇关于Go语言中goroutine的使用的文章就介绍到这了,更多相关Go语言goroutine内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • golang-gin-mgo高并发服务器搭建教程

    golang-gin-mgo高并发服务器搭建教程

    这篇文章主要介绍了golang-gin-mgo高并发服务器搭建教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Go语言的文件名、标识符、关键字和包基础教程

    Go语言的文件名、标识符、关键字和包基础教程

    Go的关键字不能被用作标识符,这是一个重要的限制,以避免命名冲突和语法混淆,这篇文章主要给大家介绍了关于Go语言文件名、标识符、关键字和包的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-06-06
  • 深入解析Golang中JSON的编码与解码

    深入解析Golang中JSON的编码与解码

    随着互联网的快速发展和数据交换的广泛应用,各种数据格式的处理成为软件开发中的关键问题,本文将介绍 Golang 中 JSON 编码与解码的相关知识,帮助大家了解其基本原理和高效应用,需要的可以收藏一下
    2023-05-05
  • golang中validator包的使用教程

    golang中validator包的使用教程

    Validator 实际上是一个验证工具,属于 golang 的第三方包,这个包中使用了各种反射技巧来提供了各种校验和约束数据的方式方法,下面就跟随小编一起来学习一下validator包的使用吧
    2023-09-09
  • Go语言接口用法实例

    Go语言接口用法实例

    这篇文章主要介绍了Go语言接口用法,实例分析了Go语言接口的功能、定义及使用技巧,需要的朋友可以参考下
    2015-02-02
  • 详细介绍Go语言之数组与切片

    详细介绍Go语言之数组与切片

    这篇文章介绍Go语言之数组与切片,数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可是任意的原始类型如整形、字符串或自定义类型。切片是数组的一个引用,因此切片是引用类型,在进行传递时,遵守引用传递的机制,下面我们就来详细了解一下该内容
    2021-10-10
  • Golang gin跨域解决方案示例

    Golang gin跨域解决方案示例

    这篇文章主要为大家介绍了Golang gin跨域解决方案,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04
  • golang双指针快速排序的实现代码

    golang双指针快速排序的实现代码

    这篇文章主要介绍了golang双指针快速排序的实现代码,通过实例代码补充介绍了Golang实现快速排序和归并排序以及堆排序算法全注释,需要的朋友可以参考下
    2024-03-03
  • Go语言使用HTTP包创建WEB服务器的方法

    Go语言使用HTTP包创建WEB服务器的方法

    这篇文章主要介绍了Go语言使用HTTP包创建WEB服务器的方法,结合实例形式分析了Go语言基于HTTP包创建WEB服务器客户端与服务器端的实现方法与相关注意事项,需要的朋友可以参考下
    2016-07-07
  • go pprof 的使用操作代码

    go pprof 的使用操作代码

    pprof 是 go 中进行性能分析的工具,可以提供可视化数据查看,这篇文章主要介绍了go pprof 的使用操作,需要的朋友可以参考下
    2022-09-09

最新评论