```
package main
import (
"fmt"
"time"
)
func putNum(intChan chan int) {
for i := 1; i <= 8000; i++ {
intChan <- i
}
close(intChan)
}
func primeNum(intChan chan int, primeChan chan int, exitChan chan bool) {
for {
time.Sleep(time.Millisecond) //由于输出流的问题,不加sleep有可能导致退出提前输出,实际执行顺序是对的
num, ok := <-intChan
if !ok {
break //取不到了
}
flag := true
//判断num是否为素数
for i := 2; i < num; i++ {
if num%i == 0 {
//num不是素数
flag = false
break
}
}
if flag {
primeChan <- num
}
}
fmt.Println("有一个primeNum协程因为取不到数据,退出")
//向exitchan写入退出标识
exitChan <- true
}
func main() {
intChan := make(chan int, 10)
for i := 0; i < 10; i++ {
intChan <- i
}
stringChan := make(chan string, 5)
for i := 0; i < 5; i++ {
stringChan <- "hello" + fmt.Sprintf("%d", i)
}
//传统的方式在遍历管道时,如果不关闭会阻塞而导致deadlock
//问题:在实际开发中,无法确定什么时候关闭该管道
//可以使用select方式解决
for {
select {
//如果intChan一直没有关闭,不会一直阻塞而导致deadlock
//会自动到下一个case匹配
case v := <-intChan:
fmt.Printf("从intchan读取的数据%d\\n", v)
time.Sleep(time.Second)
case v := <-stringChan:
fmt.Printf("从stringChan读取的数据%s\\n", v)
time.Sleep(time.Second)
default:
fmt.Printf("都取不到\\n")
time.Sleep(time.Second)
break //无法退出for循环,解决方法如下
//return(方法一)
//label goto(方法二)
}
}
}
```
- 数据类型
- 数组array
- 切片slice
- 字符串string
- map
- 结构体struct
- 方法func
- 匿名结构体(继承)
- 字段别名
- 接口interface
- 常量
- 基础语法
- 循环for
- 遍历
- 函数func
- defer
- 异常处理error
- 访问范围
- 包
- 类型断言
- 文件
- 打开文件
- 读取文件
- 写文件
- 判断是否存在
- 拷贝文件
- JSON
- 序列化
- 反序列化
- 命令行
- 杂项
- Windows下配置加速
- 相关链接
- 占位符
- 随机数rand
- 单元测试
- goroutine
- 并发和并行
- 协程和主线程
- MPG模式
- 设置CPU数量
- 全局互斥锁
- 管道
- 示例1
- 示例2
- select
- 异常捕获
- 反射
- 示例
- 示例-改变值
- 网络编程
- TCP编程
- 示例一
- redis