在Go语言中,有效的并发管理主要依赖于以下几个方面:
go
。Channels是Goroutines之间进行通信的管道。通过使用Channels,你可以在不同的Goroutines之间传递数据,从而实现同步和数据共享。func worker(done chan bool) {
fmt.Println("working...")
done <- true
}
func main() {
done := make(chan bool, 1)
go worker(done)
<-done
fmt.Println("finished")
}
import "sync"
var counter int
var lock sync.Mutex
func increment() {
lock.Lock()
defer lock.Unlock()
counter++
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
defer wg.Done()
increment()
}()
}
wg.Wait()
fmt.Println("Counter:", counter)
}
WaitGroups:WaitGroup用于等待一组Goroutines完成。当你启动一个新的Goroutine时,可以使用wg.Add(1)
增加计数器。在每个Goroutine完成时,使用wg.Done()
减少计数器。在主函数中,使用wg.Wait()
阻塞,直到所有Goroutines完成。
Context:Context用于在多个Goroutines之间传递截止时间、取消信号和其他请求范围的值。这对于控制长时间运行的任务和优雅地终止它们非常有用。
import (
"context"
"fmt"
"time"
)
func task(ctx context.Context, id int) {
for {
select {
case <-ctx.Done():
fmt.Printf("Task %d cancelled\n", id)
return
default:
fmt.Printf("Task %d working\n", id)
time.Sleep(1 * time.Second)
}
}
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
for i := 1; i <= 3; i++ {
go task(ctx, i)
}
<-ctx.Done()
fmt.Println("All tasks cancelled")
}
总之,Go语言提供了强大的并发支持,通过合理地使用Goroutines、Channels、同步原语、WaitGroups、Context以及选择合适的并发模式,你可以有效地管理并发编程。