不背锅运维:上篇:Go并发编程
2023-06-13 09:16:25 时间
- 基本使用
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() // 等待所有任务执行完成
}
- 改造一下,开启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()
}
- 将上一个例子改造成匿名函数
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()
}
- 指定占用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()
}
- 带缓冲区的通道,类似于异步的操作
package main
import "fmt"
func main() {
ch1 := make(chan int, 1) // 只能存放1个值的缓冲区通道
ch1 <- 10 // 发送
x := <-ch1 // 接收
fmt.Println(x)
close(ch1)
}
- 无缓冲区的通道,又称为同步通道
package main
import "fmt"
func main() {
ch1 := make(chan int) // 无缓冲区通道,又称为同步通道,
ch1 <- 10 // 此时这里会处于阻塞的状态,除非有另外一个goroutine去取值,它才会发送
x := <-ch1
fmt.Println(x)
close(ch1)
}
- 获取通道的容量和通道里的元素数量
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)
}
- 通道和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()
}
- 通道+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
相关文章
- go语言集成开发工具:GoLand 2022.2.1中文版「免账号登录」
- Go语言并发之并发实现、多核CPU设置、多协程间的通信、select、多协程间的同步(二十一)
- 2.Go语言之标准库学习记录(2)
- 「Go工具箱」go语言csrf库的使用方式和实现原理
- 我在斗鱼虚拟观赛直播间里看了场CS:GO Major比赛
- 「Go工具箱」推荐一个变量调试神器:go-spew
- 「Go工具箱」一个对语义化版本进行解析、比较的库:go-version
- DevOpsCamp第2期:从 《cobra - 06 持久化命令》 开始聊聊 Go语言 指针类型的使用注意事项
- Go-并发编程-goroutine 和 channel(一)
- Go-数据库操作(四)
- Go语言圣经-示例: 并发的目录遍历习题详解编程语言
- Go语言圣经–并发的循环习题详解编程语言
- 编程新精英:Go语言 Redis开发(go语言redis开发)
- SQL Server快速上手GO!(sqlserver go)
- 徒手用Go编写Redis迈向新技术世界的旅程(徒手用go写个redis)
- 请求简单而快速用Go编写的Redis请求测试(用go写的redis)
- Go语言操作Oracle轻松实现数据库编程(go语言访问oracle)
- ODBC数据驱动程序连接Oracle数据库Go语言之旅(go使用oracle)
- Oracle Go用法快速指南(oracle go用法)