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

(译)Go并发模式——Context

原文地址: https://go.dev/blog/context[] 作者:Sameer Ajmani 时间:29 July 2014 简介 footnote:ddns[这篇文章是go官网博客中的一篇,尽管文章比较早,但是较详细的描述了 context 出现的原因、使用方式,仍然值得一读。] 在 Go 服务器中,每个传入的请求都在其自己的 goroutine 中处理。请求处理程序通常会启动额外的 goroutine 来访问数据库和 RPC 服务等后端。处理请求的一组 goroutine 通常需要访问特定于请求的值,例如最终用户的身份、授权令牌和请求的截止日期。当请求被取消或超时时,所有处理该请求的 goroutines 都应该快速退出,以便系统可以回收它们正在使用的任何资源。 在 Google,我们开发了一个 context 包,可以轻松地将请求范围的值、取消信号和截止日期等跨 API 边界传递给正在处理请求的所有 goroutine。 https://go.dev/pkg/context[该软件包] 作为context公开可用 。本文介绍了如何使用该包并提供了一个完整的工作示例。 Context context 包的核心是 Context 类型: 1type Context interface { // <1> 2 Done() <-chan struct{} // <2> 3 4 Err() error // <3> 5 6 Deadline() (deadline time.Time, ok bool) // <4> 7 8 Value(key interface{}) interface{} // <5> 9} <1> Context 携带截止日期、取消信号和请求范围的跨越 API 边界的值,多个 goroutine 同时使用它的方法是安全的。 <2> Done 返回一个在此 Context 取消或超时时的通道(chan) <3> Err 错误信息说明 context 为什么被取消, 在 Done 返回的 chan 被关闭之后获取 <4> Deadline 返回 Context 被取消的时间 <5> Value 返回参数 key 关联的值,没有则返回 nil ...

2022-07-19 · 5 min · 1012 words · Hank