Golang并发编程的实现完整攻略
Golang是一门强大的并发编程语言,提供了一系列的并发编程工具来帮助我们更容易地进行并发编程。在本文中,我们将介绍Golang并发编程的基础知识,以及如何使用Golang的goroutine、channel和select语句来实现并发编程。
并发编程基础
并发编程是指同时执行多个任务的编程方式。Golang提供了goroutine来实现并发编程,goroutine是一种轻量级线程,可以与操作系统线程进行动态配对,大大降低了线程创建和销毁所需的开销。
func hello() {
fmt.Println("Hello World!")
}
func main() {
go hello()
time.Sleep(100 * time.Millisecond)
}
上面的代码定义了一个名为hello的函数,用于输出字符串"Hello World!"。在main函数中,使用go语句启动goroutine来执行hello函数,同时使用time.Sleep函数来等待goroutine的执行完成。
使用channel进行通信
channel是一种在多个goroutine间进行通信的机制,它提供了一种同步通信方式,协调各个goroutine之间的执行。
func send(c chan<- int) {
for i := 0; i < 5; i++ {
c <- i
}
close(c)
}
func recv(c <-chan int, done chan<- bool) {
for i := range c {
fmt.Println(i)
}
done <- true
}
func main() {
c := make(chan int)
done := make(chan bool)
go send(c)
go recv(c, done)
<-done
}
上面的代码定义了两个名为send和recv的函数,其中send函数用于向channel发送数据,recv函数用于从channel接收数据,并将数据打印出来。在main函数中,使用make函数创建了一个channel和一个done channel,分别用于数据传递和通知goroutine运行结束。使用go语句启动了send和recv两个goroutine,通过done channel来等待recv goroutine执行完成。
使用select语句进行多路复用
select语句用于在多个channel间进行多路复用,通过监听多个channel的读写事件来实现并发处理。
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 <= 9; j++ {
jobs <- j
}
close(jobs)
for a := 1; a <= 9; a++ {
<-results
}
}
上面的代码定义了一个名为worker的函数,用于处理接收到的工作任务,并将处理结果发送到results channel。在main函数中,使用make函数创建了一个jobs和一个results channel,分别用于接收工作任务和处理结果。使用for循环启动了3个worker goroutine来处理工作任务,并使用select语句监听jobs和results channel的读写事件,以实现并发处理。
示例说明
以下是两个示例,分别演示使用channel实现生产者-消费者模型和使用select语句监听多个channel的读写事件并实现并发处理。
生产者-消费者模型
func producer(c chan<- int) {
for i := 0; i < 5; i++ {
fmt.Println("producing", i)
c <- i
}
close(c)
}
func consumer(c <-chan int, done chan<- bool) {
for i := range c {
fmt.Println("consuming", i)
}
done <- true
}
func main() {
c := make(chan int)
done := make(chan bool)
go producer(c)
go consumer(c, done)
<-done
}
上面的代码使用channel实现了生产者-消费者模型,producer函数用于将数据发送给channel,consumer函数用于从channel接收数据。在main函数中,使用go语句同时启动producer和consumer goroutine,并使用done channel在两个goroutine之间通信,以控制主程序退出时等待所有goroutine执行完成。
使用select语句进行并发处理
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)
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 <= 9; j++ {
jobs <- j
}
close(jobs)
for a := 1; a <= 9; a++ {
select {
case r := <-results:
fmt.Println("result:", r)
}
}
}
上面的代码使用select语句监听jobs和results的读写事件,以实现并发处理。使用make函数创建了一个jobs和一个results channel,分别用于接收工作任务和处理结果。使用for循环启动了3个worker goroutine来处理工作任务,并向jobs channel发送工作任务。使用select语句监听results channel的读取事件,在获取到结果后,直接打印出来,实现了并发处理。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:golang并发编程的实现 - Python技术站