0%

Go Concurrency programming Basic Concept

Go Concurency ProgrammingGo并发编程系列的梳理, 由基础到进阶包括: 基础概念(并发, 并行, 进程, 线程, 协程), Go内置数据结构(Channel), Go内置使用语句Select, Sync, Mutex, 推荐编码范式(PipeLine, Fan-in, Fan-Out ...), Go高级使用原语(Context), Go底层实现原理: GPM, CSP, 经典案例;

本文过一遍并发编程中的基础概念: 并发, 并行, 进程, 线程, 协程, GoRoutine;

进程, 线程与协程

Process thread coroutine

  • 进程 Process:是程序在操作系统上的一次运行过程, 是系统进行资源(CPU, Memory ...)分配与调度的独立单位; 例如打开浏览器, 就是启动了一个浏览器进程, 关闭浏览器, 就是结束了一个浏览器进程, 在这期间一般称为运行时(Runtime), 系统会对浏览器进程分配其所需要的CPU, Memory等资源. 如果分配失败一般会引起Crash, 例如OOM错误, 用户常见的内存空间不足等错误;
  • 线程thread: 是进程的执行实体, 它是CPU调度与分配的独立单位, 由进程生成. 一个进程可以创建/撤销多个线程, 多个线程间可以并发执行. 例如QQ进程, 会生成一个thread用于监控QQ Message, 生成一个thread用于监听QQ Mail 等;
  • 协程coroutine: 是用户级别的线程, 其调度由用户控制, 属于轻量级的线程, 一个线程可以创建多个协程, 在Go中就是大名鼎鼎的GoRoutine概念;

并发与并行

Concurrency and parallelism

  • 并发Concurrency: 指的是多线程程序单核CPU上运行, 依赖快速时间片轮转的方式, 使得达到了伪并行的效果;
  • 并行parallelism: 指的是多线程程序多核CPU上运行;

并发与并行总是被一起提出来, 是由于其对于用户端的感受是无差别的,即程序在同时处理多个动作, 例如在浏览器上同时开启多个网页.

goroutine

goroutineGo中的coroutine实现, 是Go Concurrency Programming实现的基础特性. 通过goroutine可以轻松的将函数/方法通过并发的方式运行, 相比较于传统的创建线程的方式, 其可读性更强, 性能开销更小, 简单示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main

import (
"fmt"
"time"
)

func main() {
go sayHello() // Create a goroutine for the sayHello function
// Other code...

// Wait for goroutines to finish executing
time.Sleep(time.Second)
}

func sayHello() {
fmt.Println("Hello, goroutine!")
}

在上面的例子中, sayHello函数作为一个goroutine并发执行. 通过关键字**go**就可以轻松发起一个goroutine;

goroutine是非常轻量的, 每个goroutine初期仅占用几KB, 可以轻松开启十万级别的goroutines,而不会对性能产生太大影响。Go运行时将它们多路复用到少数操作系统线程上,runtime处理goroutines的调度和执行。

goroutines的美妙之处在于其简单易用。与传统的线程模型相比,它们使您能够以更直接和可读的方式编写并发代码。然而,请记住,在必要时,可能需要适当的同步机制(如通道或同步原语)来协调goroutine之间的通信。