- 前言
- Go 与操作系统
- Go 内部机制
- Go 基本数据类型
- 4 组合类型的使用
- 5 数据结构
- 6 Go package 中不为人知的知识
- 7 反射和接口
- 8 Go UNIX 系统编程
- 08.1 关于 UNIX 进程
- 08.2 flag 包
- 8.2 flag 包
- 08.3 io.Reader 和 io.Writer 接口
- 08.4 bufio 包
- 08.5 读取文本文件
- 08.6 从文件中读取所需的数据量
- 08.7 为什么我们使用二进制格式
- 08.8 读取 CSV 文件
- 08.9 写入文件
- 08.10 从磁盘加载和保存数据
- 08.11 再看strings包
- 08.12 关于bytes包
- 08.13 文件权限
- 08.14 处理 Unix 信号
- 08.15 Unix 管道编程
- 08.16 遍历目录树
- 08.17 使用 ePBF
- 08.18 关于 syscall.PtraceRegs
- 08.19 跟踪系统调用
- 08.20 User ID 和 group ID
- 08.21 其他资源
- 08.22 练习
- 08.23 总结
- 9 并发 Goroutines、Channel 和 Pipeline
- 10 Go 并发-进阶讨论
- 11 代码测试、优化及分析
- 12 Go 网络编程基础
- 13 网络编程 - 构建服务器与客户端
10.4.4 传送 channel 的通道
传送channel的通道 是一种特殊的通道变量,它与通道工作而不是其他类型的变量。不过,您仍然要给一个传送 channel 的通道声明一个数据类型。您可以在一行使用 chan
关键字两次定义一个传送 channel 的通道,如下所示:
c1 := make(chan chan int)
这章介绍的其他类型的通道都比传递channel的通道要简单方便。
用 chSquare.go
代码来说明传递channel的通道的使用,分为四个部分来介绍。
chSquare.go
的第一部分如下:
package main
import (
"fmt"
"os"
"strconv"
"time"
)
var times int
chSquare.go
的第二段代码如下:
func f1(cc chan chan int, f chan bool) {
c := make(chan int)
cc <- c
defer close(c)
sum := 0
select {
case x := <-c:
for i := 0; i <= x; i++ {
sum = sum + i
}
c <- sum
case <-f:
return
}
}
声明一个常规的 int
通道,您把它发送给传递通道的通道变量。然后您使用 select
表达式从常规的 int
通道读取数据和使用 f
信号通道来退出函数。
一旦您从 c
通道读取了信号值,便开始了一个 for
循环来计算从 0
到信号值的所有整数之和。接下来,您发送这个计算值给 c int
通道,执行结束。
chSquare.go
的第三部分如下:
func main() {
arguments := os.Args
if len(arguments) != 2 {
fmt.Println("Need just one integer argument!")
return
}
times, err := strconv.Atoi(arguments[1])
if err != nil {
fmt.Println(err)
return
}
cc := make(chan chan int)
上面代理里的最后一句表达式声明了一个名为 cc
的传递通道的通道变量,它是这个程序的开始,因为一切都依赖与它:cc
变量传递给 f1()
函数,并被接下来的 for
循环中使用。
chSquare.go
的其他代码如下:
for i := 1; i < times + 1; i++ {
f := make(chan bool)
go f1(cc, f)
ch := <-cc
ch <- i
for sum := range ch {
fmt.Print("Sum(", i, ")=", sum)
}
fmt.Println()
time.Sleep(time.Second)
close(f)
}
}
f
通道是一个信号通道,用来当真正的工作完成时结束 goroutine。ch := <-cc
表达式允许您从传递通道的通道获得一个常规的通道,使用 ch <-i
发送一个 int
值给它。之后,您使用 for
循环从它读取数据。尽管 f1()
函数编写为发送一个值回来,但您也可以读取多个值。注意 i
的每个值都被不同的 goroutine 执行。
信号通道的类型可以是任何您想要的类型,包括上面用到的 bool
和下节要用到的 struct{}
类型的信号通道。一个 struct{}
信号通道的优点是不能发送数据给它,这能减少错误和错误的想法。
执行 chSquare.go
将产生如下输出:
$go run chSquare.go 4
Sum(1)=1
Sum(2)=3
Sum(3)=6
Sum(4)=10
$go run chSquare.go 6
Sum(1)=1
Sum(2)=3
Sum(3)=6
Sum(4)=10
Sum(5)=15
Sum(6)=21
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论