返回

Go语言并行编程之并发、并行、Goroutine

后端

  1. 并发与并行

并发与并行常常被混为一谈,但两者之间存在着微妙的差异。

并发 是指两个或多个任务在同一时间段内交替执行,而非同时执行。任务之间通常共享相同的资源,并且任务之间的切换通常由操作系统来管理。
并行 是指两个或多个任务同时执行。任务之间通常不共享相同的资源,并且任务之间的切换通常由硬件来管理。
Go 语言支持并发编程,但并不支持并行编程。这是因为 Go 语言的内存模型是基于共享内存的,而共享内存模型不支持并行编程。

2. 串行与并发

串行 是指任务一个接一个地执行。任务之间通常共享相同的资源,并且任务之间的切换通常由操作系统来管理。
并发是指两个或多个任务在同一时间段内交替执行,而非同时执行。任务之间通常共享相同的资源,并且任务之间的切换通常由操作系统来管理。
Go 语言支持并发编程,但不支持并行编程。这是因为 Go 语言的内存模型是基于共享内存的,而共享内存模型不支持并行编程。
对比并发与串行

特征 并发 串行
任务执行 交替执行 一个接一个执行
资源共享 通常共享 通常共享
任务切换 由操作系统管理 由操作系统管理
Go 语言支持

3. Go语言中的Goroutine

Goroutine是Go语言中的一个并发原语,它允许在同一程序中同时执行多个任务。Goroutine是轻量级的,并且可以通过Go语言的runtime包来创建和管理。

Goroutine与线程非常相似,但Goroutine比线程更轻量级,并且Goroutine不需要自己管理堆栈。Goroutine的堆栈大小是由Go语言的runtime包来管理的。

Goroutine可以通过go来创建,go关键字后面跟一个函数调用。例如:

go func() {
    fmt.Println("Hello, world!")
}()

这段代码创建了一个Goroutine,该Goroutine会输出字符串"Hello, world!"

Goroutine可以通过channel来进行通信,channel是Go语言中的一种通信机制,它允许Goroutine之间传递数据。例如:

package main

import (
    "fmt"
)

func main() {
    // 创建一个channel
    ch := make(chan int)

    // 创建一个Goroutine,将数字1发送到channel
    go func() {
        ch <- 1
    }()

    // 从channel中接收数据
    num := <-ch

    // 打印接收到的数据
    fmt.Println(num)
}

这段代码创建了一个Goroutine,该Goroutine将数字1发送到channel中。主Goroutine从channel中接收数据,并将其打印出来。

4. Go语言中的并发编程实践

在Go语言中,可以通过以下几种方式实现并发编程:

  • 使用Goroutine
  • 使用channel
  • 使用sync包
  • 使用context包

使用Goroutine

Goroutine是Go语言中最常用的并发编程原语,它可以很容易地创建和管理。Goroutine的创建和管理可以通过Go语言的runtime包来完成。

使用channel

channel是Go语言中的一种通信机制,它允许Goroutine之间传递数据。channel可以用于实现Goroutine之间的同步和通信。

使用sync包

sync包提供了多种用于实现并发编程的工具,例如互斥锁、条件变量和原子变量等。

使用context包

context包提供了用于管理Goroutine生命周期的工具,例如context.Context和context.CancelFunc等。