Goroutine的概念
- 当一个函数创建为goroutine时候,就是在匿名函数前加一个go ,golang会把这个函数当做一个独立的工作单元,然后使用golang内部的逻辑处理器进行执行。golang的逻辑处理器在操作系统之上,并且会将golang的逻辑处理器和操作系统的线程进行绑定。
- golang的调度器会在任何给定的时间,都会控制哪个goroutine在哪个逻辑处理器上执行。
- 如果在逻辑处理器遇见会有阻塞的goroutine,调度器则会创建一个新的线程进行执行,执行完毕后把此goroutine在加到逻辑处理器中,然后保留当前这个线程,以备后面使用
- 并发不等于并行。并行的关键是同时做很多事情,并发是指同时管理很多事情
- 如果想让goroutine并行,则必须使用多余一个逻辑处理器,而且电脑必须多核,否则多个逻辑处理器也是在单核上并发
示例代码
package main
import (
"fmt"
"runtime"
"sync"
)
func main() {
//设置golang的逻辑处理器为 1
runtime.GOMAXPROCS(1)
//使用计数信号量 设置需要运行的goroutine 如果设置的信号量没有全部执行完成,那么主程序会阻塞
var wg sync.WaitGroup
wg.Add(2) //这里是两个 对应下面的go func 的匿名函数
fmt.Println("Start Goroutines")
//声明匿名函数,并创建一个goroutine
go func() {
defer wg.Done() //使用关键defer 在程序执行完成后执行WaitGroup减1
//打印三次小写字母
for count := 0; count < 3; count++ {
for char := 'a'; char < 'a'+26; char++ {
fmt.Printf("%c ",char)
}
}
}()
go func() {
defer wg.Done()
//打印三次大写字母
for count := 0; count < 3; count++ {
for char := 'A'; char < 'A'+26; char++ {
fmt.Printf("%c ",char)
}
}
}()
//等待goroutine结束
fmt.Println("Waiting To Finish...")
wg.Wait() //这里会阻塞主程序退出,否则goroutine执行未结束的时候主程序会直接退出
fmt.Println("Terminating Program")
}
运行结果
D:\GO\study\demo30>go run main.go
Start Goroutines
Waiting To Finish...
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z Terminating Program