goroutine引出
需要大量计算的场景,比如需要统计 1-20000之间的素数。
思路分析:
1、传统方法:循环判断各个数是不是素数(判断除以 2到n-1,能否被整除),很耗费时间🔨
2、使用并发或者并行的方式,将任务分发给多个goroutine去完成
并发从宏观上看是多个线程在同时执行,微观角度是线程来回切换执行的(比如:一次下载多集电视剧)
迅雷下载
并发和并行
并发:多线程程序在单核cpu上运行。轮询来回切换线程(0.0几毫秒间隔)
并行:多线程程序在多核cpu上运行。
go协程和go主线程
go主线程(线程、进程),一个go线程上可以起多个协程(理论上起上万个协程没有问题)
协程(goroutine)是轻量级线程(编译器做优化)。
协程特点:
- 有独立的栈空间
- 共享程序堆空间
- 调度由用户控制,开启、关闭等(主线程不由用户控制)
- 轻量级线程
协程案例
import “time”
func Sleep(d Duration)
Sleep阻塞当前go程至少d代表的时间段。d<=0时,Sleep会立刻返回。
代码
// 协程 goroutinie 案例
package main
import (
"fmt"
"strconv"
"time"
)
/*
主线程开启一个 goroutine 该协程每隔1秒输出 “hello goroutine”
主线程每隔1秒输出 “hello golang” 输出10次后退出程序
主线程和 goroutine 同时执行
*/
// 编写函数
func test() {
for i := 1; i <= 2; i++ {
fmt.Println("test() hello goroutine: " + strconv.Itoa(i))
time.Sleep(time.Second)
}
}
func main() {
// test() // 执行完 test() 函数之后才会继续执行下面的程序
go test() // 开启一个协程: goroutine (相当于是异步执行)
for i := 1; i <= 5; i++ {
fmt.Println("main() hello golang: " + strconv.Itoa(i))
time.Sleep(time.Second)
}
}
执行效果
主线程和协程执行流程图
总结
- 主线程是一个物理线程,直接作用在cpu上的。是重量级的,非常耗费cpu资源。
- 协程从主线程开启的,是轻量级的线程,是逻辑态。对资源消耗相对小。
- Golang的协程机制是重要的特点,可以轻松的开启上万个协程。其它编程语言的并发机制是一般基于线程的,开启过多的线程,资源耗费大,这里就突显Golang在并发上的优势了