GoLang教程——并发基础

Go 语言之所以在云原生时代大放异彩,很大程度上归功于其原生支持的高效并发模型。Go 采用了 Goroutine(协程)和 Channel(通道)来实现并发,这种模式被称为 CSP(通信顺序进程)。本章将带你入门 Go 的并发世界。 示例代码 1package main 2 3import ( 4 "fmt" 5 "time" 6) 7 8// 一个模拟耗时任务的函数 9func worker(id int, jobs <-chan int, results chan<- int) { 10 for j := range jobs { 11 fmt.Printf("Worker %d started job %d\n", id, j) 12 time.Sleep(time.Second) // 模拟耗时 1 秒 13 fmt.Printf("Worker %d finished job %d\n", id, j) 14 results <- j * 2 // 将结果发送回 results 通道 15 } 16} 17 18func main() { 19 // 创建两个通道:任务通道和结果通道 20 // 设置缓冲区大小为 10,防止阻塞 21 jobs := make(chan int, 10) 22 results := make(chan int, 10) 23 24 // 启动 3 个 Goroutine (Worker) 25 // 它们会并发地从 jobs 通道抢任务做 26 for w := 1; w <= 3; w++ { 27 go worker(w, jobs, results) 28 } 29 30 // 发送 5 个任务 31 for j := 1; j <= 5; j++ { 32 jobs <- j 33 } 34 close(jobs) // 关闭任务通道,告知 Worker 没有新任务了 35 36 // 接收并打印结果 37 for a := 1; a <= 5; a++ { 38 <-results 39 } 40 41 fmt.Println("All jobs finished!") 42} 关键点解释 Goroutine (协程) 使用 go 关键字 即可启动一个新的协程。例如 go funcName()。 协程比线程更轻量,启动成本极低,Go 运行时可以在少数几个 OS 线程上调度成千上万个 Goroutine。 main 函数本身也是一个 Goroutine。当 main 结束时,所有其他 Goroutine 都会被强制终止。 Channel (通道) 通道是 Goroutine 之间通信的管道。遵循“不要通过共享内存来通信,而要通过通信来共享内存”的原则。 定义:make(chan Type, capacity)。 发送:ch <- value。 接收:value := <-ch。 关闭:close(ch)。关闭后不能再发送,但可以继续接收已有的数据。 Range:for x := range ch 可以不断从通道读取数据,直到通道被关闭。 Select 选择器 select 语句是 Go 并发编程中的重要工具,用于同时等待多个通道操作。它的语法类似于 switch,但专门用于通道。 ...

2024-11-19 · 3 min · 428 words · Hank