Golang 高效并发模式

简介: 前几篇对并发编程基础元素goroutine、channel、sync包有所了解,接下来可利用这部分内容组成可使用的并发模式。

前几篇对并发编程基础元素goroutine、channel、sync包有所了解,接下来可利用这部分内容组成可使用的并发模式。

for select 循环模式

多路复用的并发模式,直到满足某条件退出for循环

// 模式1:
for{
    select{
        case <-done
          return
    default:
      //执行具体的内容
    }
}

// 模式2:
for _,val := range []int{
  select {
    case <-done:
     return
    case resCh <-val:
    ...
    if .. {
      done <- ??
    }
  }
}
  • 模式1:一直执行default语句中的任务,直到执行done后被关闭停止
  • 模式2:有限循环,resCh接收循环的值,可通过满足某条件将值传递给done,这样就可以退出当前循环,或者其他方式

select timeout模式

请求数据时,因网络不同响应时间也不同,为避免出现一直等待那些超时请求,我们需要设置一个超时时间,可使用select timeout模式

select {
    case v := <-result
      ...
    case <-time.After(5 * time.Second)
       fmt.Println("网络访问超时了")
}

主要通过time.After函数设置一个超时时间,防止因异常导致select语句无限等待。如果存在Context,可优先使用context.WithTimeout函数

Pipeline模式

管道模式(流水线模式),类似一个流水线生产,经过多个工序作业完成最后的成品。

  • 流水线由多道工序构成,每道工序通过channel将数据传递到下一个工序,即每道工序的入参都是上游工序的返回值,产生的值继续传递给下游工序
  • 每道工序对应一个函数,函数中有协程和channal,函数处理数据,并把它放在channel中,最后返回channel给下一道工序使用
  • 组织者将所有工序串联起来,形成完整的流水线
// 
func main(){
  first := build1()
  second := build2(first)
  third := build3(second)
}
//工序1
func build1(in <-chan string) <-chan string{
  out := make(chan string)
  
  go func(){
    defer close(out)
    for c:= range in{
       out <- "组装(“+c+”)"
    }
  }()
  
  return out
}
// 工序2
func build2(in <-chan string) out chan string{
  ...
}
// 工序3
func build3(in <-chan string) out chan string{
  ...
}

扇出和扇入模式

扇出:多个函数可以从同一个通道读取数据,直到通道关闭

扇入:一个函数可以从多个通道读取数据,直到通道关闭

func main(){
  in := gen(1)
  
  c1 := sq(in)
  c2 := sq(in)
  
  for n := range merge(c1,c2){
    fmt.Println(n) 
  }
}

func sq(in <-chan string) chan string{
  out := make(chan string)
  go func(){
    ...
  }
  return out 
}
目录
相关文章
|
6天前
|
Go
浅谈Golang并发控制WaitGroup
浅谈Golang并发控制WaitGroup
26 0
|
6天前
|
物联网 Go 网络性能优化
使用Go语言(Golang)可以实现MQTT协议的点对点(P2P)消息发送。MQTT协议本身支持多种消息收发模式
使用Go语言(Golang)可以实现MQTT协议的点对点(P2P)消息发送。MQTT协议本身支持多种消息收发模式【1月更文挑战第21天】【1月更文挑战第104篇】
146 1
|
6天前
|
Go
深度探讨 Golang 中并发发送 HTTP 请求的最佳技术
深度探讨 Golang 中并发发送 HTTP 请求的最佳技术
|
6天前
|
前端开发 Go
Golang深入浅出之-Go语言中的异步编程与Future/Promise模式
【5月更文挑战第3天】Go语言通过goroutines和channels实现异步编程,虽无内置Future/Promise,但可借助其特性模拟。本文探讨了如何使用channel实现Future模式,提供了异步获取URL内容长度的示例,并警示了Channel泄漏、错误处理和并发控制等常见问题。为避免这些问题,建议显式关闭channel、使用context.Context、并发控制机制及有效传播错误。理解并应用这些技巧能提升Go语言异步编程的效率和健壮性。
30 5
Golang深入浅出之-Go语言中的异步编程与Future/Promise模式
|
6天前
|
安全 Go
Golang深入浅出之-Go语言中的并发安全队列:实现与应用
【5月更文挑战第3天】本文探讨了Go语言中的并发安全队列,它是构建高性能并发系统的基础。文章介绍了两种实现方法:1) 使用`sync.Mutex`保护的简单队列,通过加锁解锁确保数据一致性;2) 使用通道(Channel)实现无锁队列,天生并发安全。同时,文中列举了并发编程中常见的死锁、数据竞争和通道阻塞问题,并给出了避免这些问题的策略,如明确锁边界、使用带缓冲通道、优雅处理关闭以及利用Go标准库。
27 5
|
6天前
|
存储 缓存 安全
Golang深入浅出之-Go语言中的并发安全容器:sync.Map与sync.Pool
Go语言中的`sync.Map`和`sync.Pool`是并发安全的容器。`sync.Map`提供并发安全的键值对存储,适合快速读取和少写入的情况。注意不要直接遍历Map,应使用`Range`方法。`sync.Pool`是对象池,用于缓存可重用对象,减少内存分配。使用时需注意对象生命周期管理和容量控制。在多goroutine环境下,这两个容器能提高性能和稳定性,但需根据场景谨慎使用,避免不当操作导致的问题。
35 4
|
6天前
|
安全 Go 开发者
Golang深入浅出之-Go语言中的CSP模型:深入理解并发哲学
【5月更文挑战第2天】Go语言的并发编程基于CSP模型,强调通过通信共享内存。核心概念是goroutines(轻量级线程)和channels(用于goroutines间安全数据传输)。常见问题包括数据竞争、死锁和goroutine管理。避免策略包括使用同步原语、复用channel和控制并发。示例展示了如何使用channel和`sync.WaitGroup`避免死锁。理解并发原则和正确应用CSP模型是编写高效安全并发程序的关键。
37 4
|
6天前
|
安全 Go 开发者
Golang深入浅出之-Go语言中的CSP模型:深入理解并发哲学
【5月更文挑战第1天】Go语言基于CSP理论,借助goroutines和channels实现独特的并发模型。Goroutine是轻量级线程,通过`go`关键字启动,而channels提供安全的通信机制。文章讨论了数据竞争、死锁和goroutine泄漏等问题及其避免方法,并提供了一个生产者消费者模型的代码示例。理解CSP和妥善处理并发问题对于编写高效、可靠的Go程序至关重要。
27 2
|
6天前
|
设计模式 Go 调度
Golang深入浅出之-Go语言中的并发模式:Pipeline、Worker Pool等
【5月更文挑战第1天】Go语言并发模拟能力强大,Pipeline和Worker Pool是常用设计模式。Pipeline通过多阶段处理实现高效并行,常见问题包括数据竞争和死锁,可借助通道和`select`避免。Worker Pool控制并发数,防止资源消耗,需注意任务分配不均和goroutine泄露,使用缓冲通道和`sync.WaitGroup`解决。理解和实践这些模式是提升Go并发性能的关键。
31 2
|
6天前
|
Go
深度探讨 Golang 中并发发送 HTTP 请求的最佳技术
深度探讨 Golang 中并发发送 HTTP 请求的最佳技术
103 0