go channel 通信通道
时间:2022-05-04
本文章向大家介绍go channel 通信通道,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
go中最重要的一种通信通道就是channel
1.给一个 nil channel 发送数据,造成永远阻塞
2.从一个 nil channel 接收数据,造成永远阻塞
3.给一个已经关闭的 channel 发送数据,引起 panic
4.从一个已经关闭的 channel 接收数据,立即返回一个零值
package main
import "fmt"
// 此channel没有设置缓存,将被阻塞,所以都是执行default
func main() {
messages := make(chan string)
signals := make(chan bool)
select {
case msg := <-messages:
fmt.Println("received message", msg)
default:
fmt.Println("no message received")
}
msg := "hi"
select {
case messages <- msg:
fmt.Println("sent message", msg)
default:
fmt.Println("no message sent")
}
select {
case msg := <-messages:
fmt.Println("received message", msg)
case sig := <-signals:
fmt.Println("received signal", sig)
default:
fmt.Println("no activity")
}
}
// 输出
// no message received
// no message sent
// no activity
复制代码
Closing Channels.
package main
import "fmt"
// 这个例子在执行workder的工作时使用jobs管道来监听
// 当jobs关闭了,表示worker执行完毕,开始退出goroutine
// goroutine的退出又使用done来监听
func main() {
jobs := make(chan int, 5)
done := make(chan bool)
go func() {
for {
j, more := <-jobs
if more {
fmt.Println("received job", j)
} else {
fmt.Println("received all jobs")
done <- true
return
}
}
}()
// 发送三个jobs worker执行
for j := 1; j <= 3; j++ {
jobs <- j
fmt.Println("sent job", j)
}
close(jobs)
fmt.Println("sent all jobs")
// worker被关闭
<-done
}
// 输出
// sent job 1
// received job 1
// sent job 2
// received job 2
// sent job 3
// received job 3
// sent all jobs
// received all jobs
复制代码
Range over Channels.
package main
import "fmt"
// 遍历channel 有两种方法:select和range
// select 在channel输入或输出才能走case
// range可以再channel 甚至close后都能遍历值
func main() {
queue := make(chan string, 2)
queue <- "one"
queue <- "two"
close(queue)
for elem := range queue {
fmt.Println(elem)
}
}
// 输出
// one
// two
package main
import "fmt"
// 此channel没有设置缓存,将被阻塞,所以都是执行default
func main() {
messages := make(chan string)
signals := make(chan bool)
select {
case msg := <-messages:
fmt.Println("received message", msg)
default:
fmt.Println("no message received")
}
msg := "hi"
select {
case messages <- msg:
fmt.Println("sent message", msg)
default:
fmt.Println("no message sent")
}
select {
case msg := <-messages:
fmt.Println("received message", msg)
case sig := <-signals:
fmt.Println("received signal", sig)
default:
fmt.Println("no activity")
}
}
// 输出
// no message received
// no message sent
// no activity
复制代码 Closing Channels.
package main
import "fmt"
// 这个例子在执行workder的工作时使用jobs管道来监听
// 当jobs关闭了,表示worker执行完毕,开始退出goroutine
// goroutine的退出又使用done来监听
func main() {
jobs := make(chan int, 5)
done := make(chan bool)
go func() {
for {
j, more := <-jobs
if more {
fmt.Println("received job", j)
} else {
fmt.Println("received all jobs")
done <- true
return
}
}
}()
// 发送三个jobs worker执行
for j := 1; j <= 3; j++ {
jobs <- j
fmt.Println("sent job", j)
}
close(jobs)
fmt.Println("sent all jobs")
// worker被关闭
<-done
}
// 输出
// sent job 1
// received job 1
// sent job 2
// received job 2
// sent job 3
// received job 3
// sent all jobs
// received all jobs
复制代码 Range over Channels.
package main
import "fmt"
// 遍历channel 有两种方法:select和range
// select 在channel输入或输出才能走case
// range可以再channel 甚至close后都能遍历值
func main() {
queue := make(chan string, 2)
queue <- "one"
queue <- "two"
close(queue)
for elem := range queue {
fmt.Println(elem)
}
}
// 输出
// one
// two
复制代码 Timers
package main
import "time"
import "fmt"
// time.NewTimer 定时一次
// 说明time是阻塞输出
func main() {
// 定时2s
timer1 := time.NewTimer(time.Second * 2)
// 阻塞输出
<-timer1.C
fmt.Println("Timer 1 expired")
timer2 := time.NewTimer(time.Second)
go func() {
<-timer2.C
fmt.Println("Timer 2 expired")
}()
stop2 := timer2.Stop()
if stop2 {
fmt.Println("Timer 2 stopped")
}
}
// 输出
// Timer 1 expired
// Timer 2 stopped
复制代码
Tickers
package main
import "time"
import "fmt"
// ticker 定时循环
func main() {
ticker := time.NewTicker(time.Millisecond * 500)
go func() {
for t := range ticker.C {
fmt.Println("Tick at", t)
}
}()
time.Sleep(time.Millisecond * 1600)
ticker.Stop()
fmt.Println("Ticker stopped")
}
// 输出
// Tick at 2012-09-23 11:29:56.487625 -0700 PDT
// Tick at 2012-09-23 11:29:56.988063 -0700 PDT
// Tick at 2012-09-23 11:29:57.488076 -0700 PDT
// Ticker stopped
- SpringBoot开发案例之整合mail队列进阶篇
- SpringBoot开发案例之集成SSL证书
- SpringBoot开发案例之整合mail队列篇
- SpringBoot开发案例之整合日志管理
- SpringBoot开发案例之奇技淫巧
- SpringBoot开发案例之整合Spring-data-jpa
- SpringBoot开发案例之整合定时任务(Scheduled)
- SpringBoot开发案例之整合mail发送服务
- SpringBoot开发案例之整合mongoDB
- Docker学习之CentOS 7安装配置
- Docker学习之搭建JavaWeb环境
- Docker学习之搭建JavaWeb环境进阶篇
- Docker学习之网络模式配置
- Docker学习之SSH连接docker容器
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 一篇文章带你使用 Python搞定对 Excel 表的读写和处理(xlsx文件的处理)
- 从 rollup 初版源码学习打包原理
- leetcode树之相同的树
- Mysql Sql 语句练习题 (50道)
- 【每日一具16】来了!扫描图片批量漂白修正软件
- 实现一个 webpack loader 和 webpack plugin
- 万字长文带你走进 JavaScript 的世界
- windows中常见后门持久化方法总结
- Python3爬虫实战【点触验证码】 — 模拟登陆bilibili
- BOM 是个什么玩意!
- Educational Codeforces Round 81 (Rated for Div. 2) B - Infinite Prefixes
- python-利用python写一个购物小程序
- Java技巧收录一 那些你相见恨晚的快捷键和代码注释模板
- Educational Codeforces Round 81 (Rated for Div. 2) C.Obtain The String
- 深入了解 webpack 模块加载原理