这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
- 并发(concurrency):把任务在不同的时间点交给处理器进行处理。在同一时间点,任务并不会同时运行。
- 并行(parallelism):把每一个任务分配给每一个处理器独立完成。在同一时间点,任务一定是同时运行。
并发和并行的区别:
并发(concurrent)指的是多个程序可以同时运行的现象,更细化的是多进程可以同时运行或者多指令可以同时运行。但这不是重点,在描述并发的时候也不会去扣这种字眼是否精确,并发的重点在于它是一种现象。并发描述的是多进程同时运行的现象。但实际上,对于单核心CPU来说,同一时刻只能运行一个进程。所以,这里的"同时运行"表示的不是真的同一时刻有多个进程运行的现象,这是并行的概念,而是提供一种功能让用户看来多个程序同时运行起来了,但实际上这些程序中的进程不是一直霸占CPU的,而是执行一会停一会。
GO语言实现并行和并发:
并发是单核在处理,例如ABCD四个任务,单核心会不断在这四个任务之间切换,肉眼看四个任务都在执行,但实际只有一个任务在执行,切换都是微秒,所以宏观上是都在执行,微观就只有一个任务在执行。
并行是多核在处理,例如ABCD四个任务,每个任务都有一个单独的核在处理,不用来回切换,都在自己干自己的,一块向前行,就是并行。
go天生支持并发,像java等语言,并发时都是交给操作系统去分配,而在go中,go内置实现了任务的调度和管理。
go中的并发由goroutine实现,类似于线程。创建goroutine只需要在函数前加一个go关键字,当我们需要并发时,只需要把任务写到函数中,然后使用go关键字开启一个goroutine去执行即可。
并发:
package main
import (
"fmt"
)
func loop(done chan bool) {
for i := 0; i < 10; i++ {
fmt.Print(i)
}
done <- true
}
func main() {
done := make(chan bool)
go loop(done)
go loop(done)
<-done
<-done
}
并发:
package main
import (
"fmt"
"runtime"
)
func loop(done chan bool) {
for i := 0; i < 100; i++ {
fmt.Printf("%d ", i)
}
done <- true
}
func main() {
runtime.GOMAXPROCS(2)
done := make(chan bool)
go loop(done)
go loop(done)
<-done
<-done
}
package main
import (
"fmt"
"runtime"
)
func loop(done chan bool) {
for i := 0; i < 100; i++ {
fmt.Printf("%d ", i)
runtime.Gosched() //// 显式地让出CPU时间给其他goroutine
}
done <- true
}
func main() {
// runtime.GOMAXPROCS(2)
done := make(chan bool)
go loop(done)
go loop(done)
<-done
<-done
}