通道是 go 语言中用于在并发函数间安全传递数据的通信机制,提供的数据竞争保护避免直接访问共享内存。通道类型包括无缓冲通道(chan t)和缓冲通道(chan t, int)。规则包括发送值(<-chan t),接收值(chan t<-),关闭通道(close(chan)),选择性接收或发送(select)。实战中,通道可用于并行计算,例如计算素数的程序中使用无缓冲输入通道,缓冲输出通道,以及用于信号计算完成的无缓冲通道。

Go 语言函数并发编程中的通道类型和规则
通道是 Go 语言中用于在并发函数之间安全地传递数据的通信机制。它们提供了一个抽象层,使函数无需直接访问共享内存,从而避免了数据竞争。
通道类型
立即学习“go语言免费学习笔记(深入)”;
通道规则
send 操作符 (<-) 将值发送到通道。必须先使用 <-chan 锁定通道,然后再发送值。receive 操作符 (->) 从通道接收值。与发送值类似,必须先使用 chan<- 锁定通道,然后再接收值。close(chan) 关闭通道。关闭后,无法再向通道发送值,但可以继续接收已发送的值。select 语句允许从多个通道进行选择性接收或发送。它提供了事件驱动的并发编程模型。实战案例
考虑一个计算素数的程序:
package main
import (
"fmt"
"math"
"sync"
"time"
)
// 工作单元
type WorkUnit struct {
n uint64
isPrime bool
finished chan bool
}
// 素数计算函数
func isPrime(n uint64) bool {
if n <= 1 {
return false
}
for i := uint64(2); i <= uint64(math.Sqrt(float64(n))); i++ {
if n%i == 0 {
return false
}
}
return true
}
// 工作器函数
func worker(in, out chan *WorkUnit, wg *sync.WaitGroup) {
defer wg.Done()
for unit := range in {
unit.isPrime = isPrime(unit.n)
close(unit.finished)
out <- unit
}
}
func main() {
// 输入通道
in := make(chan *WorkUnit)
// 输出通道
out := make(chan *WorkUnit)
// 初始化工作单元
units := make([]*WorkUnit, 500000)
for i := range units {
units[i] = &WorkUnit{
n: uint64(i),
finished: make(chan bool),
}
}
// 启动工作器
wg := &sync.WaitGroup{}
for i := 0; i < 5; i++ {
wg.Add(1)
go worker(in, out, wg)
}
// 将工作单元推送到输入通道
start := time.Now()
for _, unit := range units {
in <- unit
}
close(in)
// 从输出通道接收结果
for unit := range out {
<-unit.finished
}
elapsed := time.Since(start)
fmt.Printf("Took %s\n", elapsed)
}在这个示例中:
in 通道是无缓冲通道,用于将工作单元发送到工作器函数。out 通道是缓冲通道,用于将计算结果传回主函数。finished 通道是一个无缓冲通道,用于在工作器函数完成计算后向主函数发出信号。该程序演示了如何在 Go 中使用通道来实现并发计算,有效地利用了多个 CPU 核心。
以上就是Golang函数并发编程中通道的类型和规则的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号