共计 1977 个字符,预计需要花费 5 分钟才能阅读完成。
Go 对并发提供了弱小的原生反对,本文探讨 Go 的高级并发模式,了解这些并发模式,能够帮忙咱们编写高效的 Go 应用程序。原文: Advanced Concurrency Patterns in Go
“ 并发不是并行,但使并行成为可能。” —— Rob Pike
本文将深入探讨 Go 中的一些高级并发模式。Go 以其内置的并发原语而闻名,了解这些模式能够帮忙咱们编写更高效、可扩大的应用程序。
1. 根底 Goroutine
goroutine 是由 Go 运行时治理的轻量级线程。要启动一个 goroutine,只需在函数前应用 go
关键字。
package main | |
import ( | |
"fmt" | |
"time" | |
) | |
func sayHello() {fmt.Println("Hello from a goroutine!") | |
} | |
func main() {go sayHello() // This starts a new goroutine. | |
time.Sleep(1 * time.Second) // Give goroutine some time to execute. | |
} |
在本例中,sayHello
函数与 main
函数并发运行。
2. Channel 和 Select
channel 用于在程序之间进行通信,同步执行并确保数据安全。
根底 channel 示例
package main | |
import "fmt" | |
func main() {message := make(chan string) // create a new channel | |
go func() { // start a goroutine | |
message <- "Hello from the other side!" // send a message to the channel | |
}() | |
msg := <-message // receive a message from the channel | |
fmt.Println(msg) | |
} |
咱们能够通过 channel 平安的在例程之间发送和接管音讯。
应用 Select
select
容许程序期待多个通信操作,它就像一个针对 channel 的 switch 语句。
package main | |
import ( | |
"fmt" | |
"time" | |
) | |
func main() {ch1 := make(chan string) | |
ch2 := make(chan string) | |
go func() { | |
for { | |
ch1 <- "from ch1" | |
time.Sleep(2 * time.Second) | |
} | |
}() | |
go func() { | |
for { | |
ch2 <- "from ch2" | |
time.Sleep(3 * time.Second) | |
} | |
}() | |
go func() { | |
for { | |
select { | |
case msg1 := <-ch1: | |
fmt.Println(msg1) | |
case msg2 := <-ch2: | |
fmt.Println(msg2) | |
} | |
} | |
}() | |
select {} // keep the main function alive} |
基于select
,咱们能够同时解决多个 channel。
3. 高级模式: 工作池(Worker Pool)
工作池是一种限度运行的 goroutine 数量的办法。
工作池示例
package main | |
import ( | |
"fmt" | |
"time" | |
) | |
func worker(id int, jobs <-chan int, results chan<- int) { | |
for j := range jobs {fmt.Println("worker", id, "processing job", j) | |
time.Sleep(time.Second) | |
results <- j * 2 | |
} | |
} | |
func main() { | |
const numJobs = 5 | |
jobs := make(chan int, numJobs) | |
results := make(chan int, numJobs) | |
// start 3 workers | |
for w := 1; w <= 3; w++ {go worker(w, jobs, results) | |
} | |
// send jobs | |
for j := 1; j <= numJobs; j++ {jobs <- j} | |
close(jobs) | |
// collect results | |
for a := 1; a <= numJobs; a++ {<-results} | |
} |
工作池帮忙咱们治理和限度并发运行的 goroutine 数量。
论断
Go 中的并发 (goroutine、channel 和模式) 为开发人员提供了弱小的工具集。通过了解和利用这些概念,能够构建高性能和可伸缩的应用程序。
你好,我是俞凡,在 Motorola 做过研发,当初在 Mavenir 做技术工作,对通信、网络、后端架构、云原生、DevOps、CICD、区块链、AI 等技术始终保持着浓重的趣味,平时喜爱浏览、思考,置信继续学习、一生成长,欢送一起交流学习。为了不便大家当前能第一工夫看到文章,请敌人们关注公众号 ”DeepNoMind”,并设个星标吧,如果能一键三连(转发、点赞、在看),则能给我带来更多的反对和能源,激励我继续写下去,和大家独特成长提高!
本文由 mdnice 多平台公布