脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|shell|

服务器之家 - 脚本之家 - Golang - 正确理解Go高级并发模式

正确理解Go高级并发模式

2024-01-29 17:18DeepNoMind Golang

Go对并发提供了强大的原生支持,本文讨论Go的高级并发模式,理解这些并发模式,可以帮助我们编写高效的Go应用程序。

"并发不是并行,但使并行成为可能。" —— Rob Pike

本文将深入探讨Go中的一些高级并发模式。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用于在程序之间进行通信,同步执行并确保数据安全。

(1) 基础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安全的在例程之间发送和接收消息。

(2) 使用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和模式)为开发人员提供了强大的工具集。通过理解和利用这些概念,可以构建高性能和可伸缩的应用程序。

原文地址:https://mp.weixin.qq.com/s?__biz=MzU2MTgxODgwNA==&mid=2247487740&idx=1&sn=56a6780c6ac4ba5d040f6665ded2ca04

延伸 · 阅读

精彩推荐
  • GolangGo语言正则表达式示例

    Go语言正则表达式示例

    这篇文章主要介绍了Go语言正则表达式,结合实例形式分析了Go语言正则表达式实现字符串的匹配、查找等相关操作技巧,需要的朋友可以参考下 ...

    NNode5192020-05-04
  • GolangGo语言设置JSON的默认值操作

    Go语言设置JSON的默认值操作

    这篇文章主要介绍了Go语言设置JSON的默认值操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    小人物大青春7572021-03-22
  • Golanggolang基于websocket实现的简易聊天室程序

    golang基于websocket实现的简易聊天室程序

    这篇文章主要介绍了golang基于websocket实现的简易聊天室,分析了websocket的下载、安装及使用实现聊天室功能的相关技巧,需要的朋友可以参考下 ...

    dotcoo6982020-04-30
  • Golang详解golang开发中select多路选择

    详解golang开发中select多路选择

    这篇文章主要介绍了golang开发中select多路选择,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参...

    二十四桥明月夜335332020-09-27
  • GolangGo中的错误和异常处理最佳实践方法

    Go中的错误和异常处理最佳实践方法

    这篇文章主要介绍了Go中的错误和异常处理最佳实践方法,文章围绕主题展开详细的内容戒杀,具有一定的参考价值,需要的小伙伴可以参考一下...

    7small7​​​​​​​11862022-11-14
  • Golanggolang 实现两个结构体复制字段

    golang 实现两个结构体复制字段

    这篇文章主要介绍了golang 实现两个结构体复制字段,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    butterfly52113148962021-06-06
  • GolangGo语言声明一个多行字符串的变量

    Go语言声明一个多行字符串的变量

    这篇文章主要介绍了Go语言声明一个多行字符串的变量的方法和示例,非常简单实用,有需要的小伙伴可以参考下。 ...

    脚本之家9212020-04-25
  • Golanggo调用shell命令两种方式实现(有无返回值)

    go调用shell命令两种方式实现(有无返回值)

    本文主要介绍了go调用shell命令两种方式实现(有无返回值),主要用于执行shell命令,并且返回shell的标准输出,具有一定的参考价值,感兴趣的可以了解一下...

    风逸者儿9672022-01-20