Go 并发 第1部分:基础与同步

发布: (2026年5月1日 GMT+8 09:25)
4 分钟阅读
原文: Dev.to

Source: Dev.to

基础并发与同步

首先先了解这两个词的含义

Concurrency

定义是:在同一时间段内处理多个任务的能力
每个任务不一定要同时执行,只要交替执行也算并发
关键特征是每个任务的起始时间有 overlap

Parallelism

定义是:能够同时在硬件上处理多个任务,需要硬件支持

注意:并发可以是并行,也可以不是,这取决于与硬件的映射

即使没有并行运行,并发仍能提升速度,因为一般任务会等待某些操作(例如从内存读取或写入),在等待期间切换到其他任务可以提升整体效率

Go 语言中的并发

Go 内置并发,无需依赖外部库

GOMAXPROCS

设置可同时运行 Go 代码的 OS 线程数

runtime.GOMAXPROCS(4)   // ตั้งค่าจากโค้ด

或通过环境变量

export GOMAXPROCS=4

从 Go 1.5 起,GOMAXPROCS 的默认值等于机器的逻辑 CPU 数量,通常不需要修改。设置过高可能导致上下文切换增多,反而降低性能

Goroutine

Go 使用 goroutine,它是轻量级线程(在单个 OS 线程中可以有数千甚至数万),由 Go Runtime Scheduler 调度

程序启动时会创建第一个 goroutine,称为 main routine。要实现并发,只需在函数调用前加上关键字 go

基础示例

package main

import (
	"fmt"
	"time"
)

func main() {
	go fmt.Println("New Routine")
	fmt.Println("Main Routine")
}

运行结果只会看到

Main Routine

因为 main() 在新 goroutine 执行前就结束了

正确等待 goroutine 的方式

不建议使用 time.Sleep,因为无法确定需要等待多长时间。推荐使用同步机制,例如 sync.WaitGroup

使用 sync 包进行同步

sync.WaitGroup

WaitGroup 用于记录需要等待的任务计数

  • Add(n) – 增加计数
  • Done() – 任务完成后递减计数
  • Wait() – 等待计数归零

示例

package main

import (
	"fmt"
	"sync"
)

func foo(wg *sync.WaitGroup) {
	fmt.Println("New Routine")
	wg.Done() // บอกว่ารันจบแล้ว
}

func main() {
	var wg sync.WaitGroup
	wg.Add(2)          // มี 2 งานที่ต้องรอ
	go foo(&wg)
	go foo(&wg)
	wg.Wait()          // รอจนกว่างานทั้งหมดเสร็จ
	fmt.Println("Main Routine")
}

输出

New Routine
New Routine
Main Routine

sync.Once

Once 确保指定函数只会执行一次,即使被多个 goroutine 调用

示例

package main

import (
	"fmt"
	"sync"
)

func setup() {
	fmt.Println("Setup")
}

func main() {
	var once sync.Once
	var wg sync.WaitGroup

	for i := 0; i  // (โค้ดตัวอย่างนี้ยังไม่สมบูรณ์ในต้นฉบับ)
}

注意:在 Go 中我们通常避免直接共享全局变量并修改其值,而是使用 channel,这将在下一篇文章中说明.

0 浏览
Back to Blog

相关文章

阅读更多 »

Go 并发 第2部分:Channel

Channel “不要通过共享内存进行通信;而是通过通信来共享内存”。在 Go 中,goroutine 通常通过 Channel 交换数据,而不是使用 mutex。

Go 零值:var 与 :=

Go 有两种声明变量的方式:var 和 :=。它们存在的原因不同,规则也不同。了解何时使用每一种可以避免低级错误和 c…

模型越智能,节省越多。

神话:更智能的模型会让插件变得多余。自从 WOZCODE 推出以来,许多 Claude Code 高级用户低声说插件的优势将会消失。