Go语言进阶
并发VS并行
- 并发:是指在同一处理器上同时处理多个任务。它是通过任务切换的方式,在很小的时间片内交替执行多个任务,给人的感觉是同时进行的。而并行则是指多个处理器或者多个核心的处理器同时处理多个不同的任务,每个处理器或者核心都负责执行自己的任务,真正地同时进行。
比喻的话,可以说并发就像一个人“同时”做三件事(此处假设三件事为:吃零食、看电视、玩手机),不过他可能一会儿吃零食,然后抬头看看电视,再低头玩玩手机,反复循环。但他不能在同一时间做三件事,即不是真正的“同时”。
- 并行是指在同一时刻,多个处理器上同时执行多条指令。
根据我个人的理解,同样比喻就是:并行则像是三个人同时做三件事,每个人专注地完成自己的事(吃零食、看电视、玩手机)。
线程VS协程
-
线程:进程的执行单元,比进程更小的可独立运行的基本单位。线程拥有自己的寄存器上下文和栈,但不拥有系统资源,只拥有少量必要的资源。线程可以共享进程所拥有的全部资源,通信一般通过共享内存进行。
-
协程:是一种用户态的轻量级线程,完全由用户控制调度。协程拥有自己的寄存器上下文和栈,调度切换时,保存寄存器上下文和栈到其他地方,在切换回来时恢复先前保存的上下文和栈。由于直接操作栈,基本没有内核切换的开销,可以不加锁地访问全局变量,因此上下文切换非常快。
-
对比线程,一个线程可以拥有多个协程,线程是同步机制,而协程则是异步的。协程能保留上一次调用的状态,每次切换到协程时,相当于进入上一次调用的状态。
Go并发
开启一个goroutine
- Go语言的协程goroutine。它可以被描述为一种轻量级线程。与传统的操作系统线程不同,goroutine将一个操作系统线程分段使用,并通过Go语言自身的调度器实现协作式调度。因此,它被称为绿色线程或微线程。
- 与传统协程相比,Go语言的goroutine具有一些特点。例如,当一个goroutine发现自己被阻塞时,它可以启动新的微线程来处理其他任务。这种能力使得goroutine能够更好地利用多核CPU,提高程序的并发性能。总的来说,goroutine是一种轻量级、高效且能够自动管理调度的线程机制。
语法格式:go 函数名( 参数列表 )
go func() {
//函数体
}
}()
在暂未深入接触过其他语言的并发编程的情况下,我已经被Go并发优雅的写法吸引了。可以说是十分简洁
通过通信共享内存
Goroutine 和 channel 是 Go 语言并发编程的 两大基石。
- Goroutine 用于执行并发任务,channel 用于 goroutine 之间的同步、通信。
- 因为 channel 是一个引用类型,所以在它被初始化之前,它的值是 nil,channel 使用 make 函数进行初始化。
src := make(chan int) - 通道可以设置缓冲区,通过 make 的第二个参数指定缓冲区大小
dest := make(chan int, 3) - 操作符
<-用于指定通道的方向,发送或接收。如果未指定方向,则为双向通道。src <- i
func CalSquare() {
src := make(chan int)
dest := make(chan int, 3)
go func() {
defer close(src)
for i := 0; i < 10; i++ {
src <- i
}
}()
go func() {
defer close(dest)
for i := range src {
dest <- i * i
}
}()
for i := range dest {
fmt.Println(i)
}
}
上述代码中带缓冲的channel dest规避生产与消费速度不匹配问题
至此,go语言的并发编程还是十分简洁