本文主要是介绍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 的奥秘的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!