在Go语言中,处理并发编程中的异常需要使用通道(channel)和sync.Mutex
或sync.RWMutex
来确保数据的一致性和同步。这里有一个简单的示例,展示了如何在Go语言中处理并发编程中的异常:
package main
import (
"errors"
"fmt"
"sync"
)
type Task struct {
ID int
Message string
}
func worker(id int, tasks <-chan Task, results chan<- error, wg *sync.WaitGroup, mu *sync.Mutex) {
defer wg.Done()
for task := range tasks {
mu.Lock()
// 模拟任务执行过程中可能出现的异常
if task.ID == 3 {
mu.Unlock()
results <- errors.New("task 3 encountered an error")
continue
}
mu.Unlock()
// 模拟任务正常执行
fmt.Printf("Worker %d processed task %d\n", id, task.ID)
results <- nil
}
}
func main() {
const numWorkers = 5
const numTasks = 10
tasks := make(chan Task, numTasks)
results := make(chan error, numTasks)
var wg sync.WaitGroup
var mu sync.Mutex
// 启动工作协程
for i := 1; i <= numWorkers; i++ {
wg.Add(1)
go worker(i, tasks, results, &wg, &mu)
}
// 向任务通道发送任务
for i := 1; i <= numTasks; i++ {
tasks <- Task{ID: i}
}
close(tasks)
// 等待所有工作协程完成
wg.Wait()
close(results)
// 处理结果
for err := range results {
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Success")
}
}
}
在这个示例中,我们创建了一个worker
函数,它接收一个任务通道、一个结果通道、一个等待组和一个互斥锁。工作协程从任务通道中获取任务,执行任务,并将结果发送到结果通道。如果在执行任务过程中遇到异常(例如任务ID为3),我们将错误发送到结果通道,并继续处理下一个任务。
在main
函数中,我们启动了5个工作协程,并向任务通道发送了10个任务。然后,我们等待所有工作协程完成,并处理结果通道中的错误和成功消息。