Go 协程基础:轻松入门并发编程,解析 Goroutines 的奥秘

2023-12-10 03:36

本文主要是介绍Go 协程基础:轻松入门并发编程,解析 Goroutines 的奥秘,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、协程基本使用

1、启动一个协程
  • 主线程中每个100毫秒打印一次,总共打印2次
  • 另外开启一个协程,打印10次
  • 情况一:打印是交替,证明是并行的
  • 情况二:开启的协程打印2次,就退出了(因为主线程退出了)
package mainimport ("fmt""time"
)func test() {for i :=o;i<10;i++ {fmt.PrintIn("test() 你好golang")time.Sleep(time.Millisecond * 100)}
}func main() {go test()    //表示开启一个协程for i:=0;i<2;i++ {fmt.PrintIn("main() 你好golang")time.Sleep(time.Millisecond * 100)}
}
/*
main() 你好golang
test() 你好golang
main() 你好golang
test() 你好golang
test() 你好golang
*/
 2、WaitGroup等待协程执行完毕
  • 主线程退出后所有的协程无论有没有执行完毕都会退出
  • 所以我们在主进程中可以通过WaitGroup等待协程执行完毕
    • sync.WaitGroup内部维护者一个计数器,计数器的值可以增加和减少
    • 例如当我们启动了N个并发任务时,就将计数器值增加N
    • 每个任务完成时通过调用Done()方法将计数器减1
    • 通过调用Wait来等待并发任务执行完,当计数器值为0时,表示所有并发任务已经完成

var wg sync.waitGroup      //第一步:定义一个计数器

wg.Add(1)                        //第二步:开启一个协程计数器+1

wg.Done()                        //第三步:协程执行完毕,计数器-1

wg.Wait()                        //第四步:计数器为0时退出

package mainimport ("fmt""sync""time"
)var wg sync.WaitGroup         //第一步:定义一个计数器func  test1() {for i :=0;i<10;i++ {fmt.PrintIn("test1() 你好golang",i)time.Sleep(time.Millisecond * 100)}wg.Done()    //协程计数器-1    //第三步:协程执行玩不,计数器-1
}func  test2() {for i :=0;i<2;i++ {fmt.PrintIn("test2() 你好golang",i)time.Sleep(time.Millisecond * 100)}wg.Done()    //协程计数器-1   
}func main() {wg.Add(1)    //协程计数器+1     第二不:开启一个协程计数器+1go test1()    //表示开启一个协程wg.Add(1)    //协程计数器+1go test2()    //表示开启一个协程wg.Wait()    //等待协程执行完毕... 第四步:计数器为0时退出fmt.PrintIn("主线程退出...")}/*
test2() 你好golang- 0
test1() 你好golang- 0
.....
test1() 你好golang- 8
test1() 你好golang- 9
主线程退出...
*/

 二、多协程案例

1、开启多个协程
  • 在Go语言中实现并发就是这样简单,我们还可以启动多个goroutine
  • 这里使用了sync.WaitGroup来实现等待goroutine执行完毕
  • 多次执行上面的代码,会发现每次打印的数字的顺序都不一致
  • 这是因为10个goroutine是并发执行的,而goroutine的调度是随机的
package mainimport ("fmt""sync"
)var wg sync.WaitGroupfunc hello(i int){defer wg.Done()    //goroutine结束就登记-1fmt.PrintIn("Hello Goroutine!",i)
}func main() {for i :=0;i<10;i++ {wg.Add(1)    //启动一个goroutine就登记+1go hello(i)}wg.Wait()    //等待所有登记的goroutine都结束
}
2、多协程统计素数
  • 需求:要统计1-120000的数字中哪些是素数?goroutine for循环实现
  • 协程 统计 1-30000
  • 协程 统计 30001-60000
  •  协程 统计 60001-90000

  • 协程 统计 90001-120000

  • start:(n-1)*30000+1 end:n*30000

package main
import ("fmt""sync""time"
)
var wg sync.WaitGroupfunc test(n int) {for num := (n-1)*30000 + 1; num < n*30000; num++ {if num > 1 {var flag = truefor i := 2; i < num; i++ {if num%i == 0 {flag = falsebreak}}if flag {fmt.Println(num, "是素数")}}}wg.Done()
}func main() {start := time.Now().Unix()for i := 1; i <= 4; i++ {wg.Add(1)go test(i)}wg.Wait()fmt.Println("执行完毕")end := time.Now().Unix()fmt.Println(end - start) //1毫秒
}

这篇关于Go 协程基础:轻松入门并发编程,解析 Goroutines 的奥秘的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/475916

相关文章

Python基础语法中defaultdict的使用小结

《Python基础语法中defaultdict的使用小结》Python的defaultdict是collections模块中提供的一种特殊的字典类型,它与普通的字典(dict)有着相似的功能,本文主要... 目录示例1示例2python的defaultdict是collections模块中提供的一种特殊的字

Java图片压缩三种高效压缩方案详细解析

《Java图片压缩三种高效压缩方案详细解析》图片压缩通常涉及减少图片的尺寸缩放、调整图片的质量(针对JPEG、PNG等)、使用特定的算法来减少图片的数据量等,:本文主要介绍Java图片压缩三种高效... 目录一、基于OpenCV的智能尺寸压缩技术亮点:适用场景:二、JPEG质量参数压缩关键技术:压缩效果对比

关于WebSocket协议状态码解析

《关于WebSocket协议状态码解析》:本文主要介绍关于WebSocket协议状态码的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录WebSocket协议状态码解析1. 引言2. WebSocket协议状态码概述3. WebSocket协议状态码详解3

CSS Padding 和 Margin 区别全解析

《CSSPadding和Margin区别全解析》CSS中的padding和margin是两个非常基础且重要的属性,它们用于控制元素周围的空白区域,本文将详细介绍padding和... 目录css Padding 和 Margin 全解析1. Padding: 内边距2. Margin: 外边距3. Padd

Python基础文件操作方法超详细讲解(详解版)

《Python基础文件操作方法超详细讲解(详解版)》文件就是操作系统为用户或应用程序提供的一个读写硬盘的虚拟单位,文件的核心操作就是读和写,:本文主要介绍Python基础文件操作方法超详细讲解的相... 目录一、文件操作1. 文件打开与关闭1.1 打开文件1.2 关闭文件2. 访问模式及说明二、文件读写1.

Oracle数据库常见字段类型大全以及超详细解析

《Oracle数据库常见字段类型大全以及超详细解析》在Oracle数据库中查询特定表的字段个数通常需要使用SQL语句来完成,:本文主要介绍Oracle数据库常见字段类型大全以及超详细解析,文中通过... 目录前言一、字符类型(Character)1、CHAR:定长字符数据类型2、VARCHAR2:变长字符数

Go标准库常见错误分析和解决办法

《Go标准库常见错误分析和解决办法》Go语言的标准库为开发者提供了丰富且高效的工具,涵盖了从网络编程到文件操作等各个方面,然而,标准库虽好,使用不当却可能适得其反,正所谓工欲善其事,必先利其器,本文将... 目录1. 使用了错误的time.Duration2. time.After导致的内存泄漏3. jsO

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@