zl程序教程

您现在的位置是:首页 >  后端

当前栏目

不背锅运维:上篇:Go并发编程

2023-06-13 09:16:25 时间
  1. 基本使用
package main

import (
 "fmt"
 "sync"
)

var wg sync.WaitGroup

func hello() {
 fmt.Println("hello func...")
 wg.Done() // 通知计数器减1
}

func main() {

 wg.Add(4) // 计数器,4个并发任务
 go hello()
 go hello()
 go hello()
 go hello()
 fmt.Println("main func!")

 wg.Wait() // 等待所有任务执行完成
}
  1. 改造一下,开启10000个goroutine
package main

import (
 "fmt"
 "sync"
)

var wg sync.WaitGroup

func hello(i int) {
 fmt.Println("hello func...", i)
 wg.Done()
}

func main() {
 // wg.Add(10000)
 for i := 0; i < 10000; i++ {
  wg.Add(1)
  go hello(i)
 }
 fmt.Println("main func!")

 wg.Wait()
}
  1. 将上一个例子改造成匿名函数
package main

import (
 "fmt"
 "sync"
)

var wg sync.WaitGroup

func main() {
 // wg.Add(10000)
 for i := 0; i < 10000; i++ {
  go func(i int) {
   fmt.Println("hello...", i)
  }(i)
 }
 fmt.Println("main func!")

 wg.Wait()
}
  1. 指定占用CPU核心数
package main

import (
 "fmt"
 "runtime"
 "sync"
)

var wg sync.WaitGroup

func test1() {
 for i := 0; i < 10; i++ {
  fmt.Println("func test1...", i)
 }
}

func test2() {
 for i := 0; i < 10; i++ {
  fmt.Println("func test2...", i)
 }
}

func main() {
 runtime.GOMAXPROCS(1) // 只占用1个CPU核心
 wg.Add(2)
 go test1()
 go test2()
 wg.Wait()
}
  1. 带缓冲区的通道,类似于异步的操作
package main

import "fmt"

func main() {
 ch1 := make(chan int, 1) // 只能存放1个值的缓冲区通道
 ch1 <- 10  // 发送
 x := <-ch1 // 接收
 fmt.Println(x)
 close(ch1)
}
  1. 无缓冲区的通道,又称为同步通道
package main

import "fmt"

func main() {
 ch1 := make(chan int) // 无缓冲区通道,又称为同步通道,
 ch1 <- 10             // 此时这里会处于阻塞的状态,除非有另外一个goroutine去取值,它才会发送
 x := <-ch1
 fmt.Println(x)
 close(ch1)
}
  1. 获取通道的容量和通道里的元素数量
package main

import "fmt"

func main() {
 ch1 := make(chan int, 10)
 ch1 <- 89
 ch1 <- 70
 fmt.Println(len(ch1)) // 获取通道中元素的数量
 fmt.Println(cap(ch1)) // 获取通道的容量
 close(ch1)
}
  1. 通道和goroutine的小栗子
package main

import (
 "fmt"
 "sync"
)

type myinterface interface{}

var ch1 = make(chan myinterface, 1)
var wg sync.WaitGroup

func sendData(i myinterface) {
 fmt.Printf("向通道发送 %v 成功\n", i)
 ch1 <- i
 wg.Done()
}

func readData() {
 v := <-ch1
 fmt.Println("从通道获取的值:", v)
 wg.Done()
}

func main() {
 nameArray := []string{"ttr", "tantianran"}

 wg.Add(2)
 go sendData(nameArray)
 go readData()
 wg.Wait()
}
  1. 通道+goroutine,实现协同干活例子2
package main

import "fmt"

func producer(ch chan int) {
 for i := 0; i < 10; i++ {
  ch <- i
 }
 close(ch)
}

func consumer(ch1 chan int, ch2 chan int) {
 for {
  v, ok := <-ch1
  if !ok {
   break
  }
  ch2 <- v * 2
 }
 close(ch2)
}

func main() {
 ch1 := make(chan int, 100)
 ch2 := make(chan int, 200)

 go producer(ch1)
 go consumer(ch1, ch2)

 for i := range ch2 {
  fmt.Println(i)
 }
}

本文转载于(喜欢的盆友关注我们哦):https://mp.weixin.qq.com/s/_X2nEo2BJ2ScdbUyQHxB8A