管道和消息队列是 go 中用于 goroutine 通信的原语。管道是无缓冲通道,立即传递数据;消息队列是缓冲通道,允许存储多个消息。实战案例 中,管道可用于并行处理任务,如将一组任务发送到管道并使用 goroutine 池并行处理。 内容来自samhan666
copyright zvvq
Go 中的管道与消息队列
zvvq好,好zvvq
在 Go 中,管道和消息队列是用于 goroutine 之间通信的两个基本原语。 内容来自samhan666
管道 zvvq.cn
“go语言免费”;
内容来自samhan666
管道是无缓冲的通信通道,数据会立即从写入端传递到读取端。管道通常用于在 goroutine 之间传递小块数据。
copyright zvvq
创建管道:
1
2 copyright zvvq
3 zvvq.cn
4 zvvq好,好zvvq
5 内容来自zvvq
6 zvvq好,好zvvq
7 内容来自zvvq,别采集哟
8 本文来自zvvq
9 zvvq好,好zvvq
10
zvvq
11 内容来自zvvq,别采集哟
12
13 内容来自samhan666
14
15 内容来自zvvq,别采集哟
package main
import "fmt" 内容来自samhan
func main() {
// 创建一个管道 内容来自samhan666
ch := make(chan int) zvvq好,好zvvq
// 写入数据
copyright zvvq
ch <- 42 内容来自samhan
// 读取数据 zvvq
v := <-ch zvvq好,好zvvq
fmt.Println(v) // 输出 42 内容来自samhan666
}
zvvq
消息队列
copyright zvvq
消息队列是一种缓冲的通信通道,允许在写入端和读取端之间存储多个消息。这使得 goroutine 可以按自己的节奏发送和接收消息,而不必担心丢失或阻塞。 zvvq
使用内置的 sync.Mutex 和 sync.Cond 创建一个简单的消息队列: zvvq好,好zvvq
1 内容来自zvvq
2 内容来自samhan
3 copyright zvvq
4
5 zvvq.cn
6
7 zvvq
8 zvvq好,好zvvq
9 copyright zvvq
10 内容来自samhan
11 内容来自samhan
12
内容来自samhan
13
本文来自zvvq
14 内容来自samhan666
15
16 内容来自samhan
17
内容来自zvvq
18 本文来自zvvq
19 内容来自zvvq,别采集哟
20
21 内容来自samhan
22 内容来自zvvq
23
24 zvvq
25
26
27 内容来自zvvq
28
zvvq.cn
29 内容来自samhan
30
内容来自zvvq,别采集哟
31 本文来自zvvq
32
33
copyright zvvq
34
zvvq好,好zvvq
35 zvvq.cn
36
37
copyright zvvq
38
copyright zvvq
39 zvvq
40 本文来自zvvq
41
内容来自zvvq,别采集哟
42
内容来自samhan666
43
内容来自samhan666
44
内容来自samhan
package main
import (
"fmt"
内容来自zvvq
"sync" zvvq.cn
"time"
本文来自zvvq
)
func main() {
copyright zvvq
// 创建一个消息队列 zvvq.cn
var (
内容来自zvvq,别采集哟
queue = []int{}
mu sync.Mutex
cond sync.Cond zvvq.cn
) 内容来自samhan666
// 启动一个生产者 goroutine zvvq.cn
go func() { 内容来自samhan
for { 内容来自zvvq,别采集哟
mu.Lock()
zvvq.cn
queue = append(queue, 42)
本文来自zvvq
cond.Signal() zvvq.cn
mu.Unlock() zvvq.cn
time.Sleep(time.Second)
内容来自zvvq
} copyright zvvq
}() 本文来自zvvq
// 启动一个消费者 goroutine
内容来自samhan
go func() {
for { 内容来自zvvq
mu.Lock()
内容来自zvvq
for len(queue) == 0 {
cond.Wait() 本文来自zvvq
} zvvq好,好zvvq
v := queue[0]
内容来自zvvq,别采集哟
queue = queue[1:]
zvvq.cn
mu.Unlock()
fmt.Println(v) // 输出 42 zvvq好,好zvvq
} 内容来自samhan
}()
// 等待 goroutine 退出
内容来自zvvq
time.Sleep(time.Second 5) 内容来自zvvq
} 内容来自samhan666
实战案例 :并行处理任务 zvvq好,好zvvq
管道或消息队列可以用于并行处理任务。以下是一个示例,说明如何使用管道并行处理一组任务:
1 zvvq.cn
2
3 内容来自samhan666
4 内容来自samhan
5 本文来自zvvq
6
7 内容来自zvvq
8
9
10
11
zvvq
12 copyright zvvq
13 内容来自samhan666
14 zvvq
15 内容来自zvvq
16 zvvq好,好zvvq
17
内容来自zvvq,别采集哟
18 内容来自samhan666
19 zvvq好,好zvvq
20 内容来自samhan666
21
内容来自samhan
22 zvvq
23
内容来自zvvq,别采集哟
24
25 内容来自samhan
26 本文来自zvvq
27 zvvq.cn
28 内容来自zvvq
29
30 内容来自zvvq
31 zvvq
32
zvvq
33
zvvq
34 copyright zvvq
35
36
37
package main
zvvq.cn
import ( zvvq.cn
"fmt"
"sync" 内容来自zvvq
) zvvq好,好zvvq
func main() {
// 定义任务 zvvq好,好zvvq
tasks := []int{1, 2, 3, 4, 5}
内容来自samhan
// 创建管道 zvvq
ch := make(chan int) zvvq好,好zvvq
// 启动 goroutine 池来处理任务 zvvq
var wg sync.WaitGroup
zvvq.cn
for i := 0; i < 4; i++ {
内容来自zvvq
wg.Add(1)
zvvq.cn
go func(ch chan int) { 本文来自zvvq
for task := range ch { 内容来自samhan666
fmt.Println(task) copyright zvvq
} zvvq.cn
wg.Done() zvvq
}(ch) 内容来自zvvq
} 内容来自zvvq,别采集哟
// 将任务发送到管道 内容来自samhan
for _, task := range tasks { zvvq.cn
ch <- task 内容来自samhan
} copyright zvvq
// 关闭管道 内容来自zvvq,别采集哟
close(ch)
// 等待 goroutine 池完成 copyright zvvq
wg.Wait() copyright zvvq
}
内容来自samhan666
以上就是golang并发编程中的管道与消息队列的详细内容,更多请关注其它相关文章! 内容来自samhan666