乐闻世界logo
搜索文章和话题

Go 中常见的并发模式有哪些?

1 个月前提问
1 个月前修改
浏览次数16

1个答案

1

在Go语言中,常见的并发模式主要有以下几种:

1. 使用 goroutine 和 channel

Goroutines 是Go中实现并发的基本单位,而channels则用于在不同的goroutines之间安全地传递消息。这种模式可以很好地解耦并行任务之间的交互并保证数据的一致性。

示例:

go
package main import ( "fmt" "time" ) func worker(id int, jobs <-chan int, results chan<- int) { for j := range jobs { fmt.Println("worker", id, "started job", j) time.Sleep(time.Second) fmt.Println("worker", id, "finished job", j) results <- j * 2 } } func main() { jobs := make(chan int, 100) results := make(chan int, 100) for w := 1; w <= 3; w++ { go worker(w, jobs, results) } for j := 1; j <= 5; j++ { jobs <- j } close(jobs) for a := 1; a <= 5; a++ { <-results } }

2. WaitGroup

使用sync.WaitGroup来等待一组goroutines完成。这是一种很常见的方式来同步并行处理的结束。

示例:

go
package main import ( "fmt" "sync" "time" ) func worker(id int, wg *sync.WaitGroup) { defer wg.Done() fmt.Printf("Worker %d starting\n", id) time.Sleep(time.Second) fmt.Printf("Worker %d done\n", id) } func main() { var wg sync.WaitGroup for i := 1; i <= 5; i++ { wg.Add(1) go worker(i, &wg) } wg.Wait() }

3. 使用context控制goroutines

context可以用来发送取消信号到goroutines中,这在你需要控制可能长时间运行或需要提前停止的并发操作时非常有用。

示例:

go
package main import ( "context" "fmt" "time" ) func operation(ctx context.Context, duration time.Duration) { select { case <-time.After(duration): fmt.Println("完成操作") case <-ctx.Done(): fmt.Println("中断操作") } } func main() { ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond) defer cancel() go operation(ctx, 100*time.Millisecond) time.Sleep(100 * time.Millisecond) }

4. 锁(如 sync.Mutex 和 sync.RWMutex)

当涉及到状态管理且多个goroutines需要读写相同的资源时,使用锁可以保护这些资源不会因并发访问而发生竞态条件。

示例:

go
package main import ( "fmt" "sync" ) var ( mutex sync.Mutex balance int ) func deposit(value int, wg *sync.WaitGroup) { mutex.Lock() fmt.Printf("Adding %d to balance\n", value) balance += value mutex.Unlock() wg.Done() } func main() { var wg sync.WaitGroup balance = 100 wg.Add(2) go deposit(200, &wg) go deposit(300, &wg) wg.Wait() fmt.Printf("New Balance %d\n", balance) }

这些模式是Go语言中处理并发的几种基本和常用方法。每种方法有其适用场景,根据具体需求选择合适的模式非常关键。

2024年8月7日 21:50 回复

你的答案