惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Security Archives - TechRepublic
MongoDB | Blog
MongoDB | Blog
量子位
博客园 - 叶小钗
罗磊的独立博客
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Hacker News: Ask HN
Hacker News: Ask HN
MyScale Blog
MyScale Blog
GbyAI
GbyAI
Help Net Security
Help Net Security
Y
Y Combinator Blog
Engineering at Meta
Engineering at Meta
Hacker News - Newest:
Hacker News - Newest: "LLM"
Latest news
Latest news
H
Hacker News: Front Page
Blog — PlanetScale
Blog — PlanetScale
雷峰网
雷峰网
Microsoft Azure Blog
Microsoft Azure Blog
P
Proofpoint News Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
Scott Helme
Scott Helme
S
Schneier on Security
博客园 - 司徒正美
Hugging Face - Blog
Hugging Face - Blog
S
Security @ Cisco Blogs
Recorded Future
Recorded Future
S
Securelist
博客园 - Franky
Application and Cybersecurity Blog
Application and Cybersecurity Blog
A
About on SuperTechFans
N
News and Events Feed by Topic
AI
AI
T
Tenable Blog
N
News | PayPal Newsroom
C
Cybersecurity and Infrastructure Security Agency CISA
V
V2EX - 技术
T
Threat Research - Cisco Blogs
Cisco Talos Blog
Cisco Talos Blog
L
LINUX DO - 热门话题
N
Netflix TechBlog - Medium
S
SegmentFault 最新的问题
T
The Blog of Author Tim Ferriss
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Google Online Security Blog
Google Online Security Blog
S
Security Affairs
Webroot Blog
Webroot Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
博客园 - 三生石上(FineUI控件)
C
Comments on: Blog
G
GRAHAM CLULEY

博客园 - 网鱼

Twitter的分布式自增ID雪花算法snowflake (Java版) 雪花算法:生成分布式全局唯一ID 数据加密共享与签名方案 Java 8中处理集合的优雅姿势——Stream 消息中间件选型分析——从Kafka与RabbitMQ的对比来看全局 从概念到底层技术,一文看懂区块链架构设计(附知识图谱) 以太坊源码分析——BlockChain 超级账本实践——基于docker从零搭建联盟链 Hyperledger Fabric V1.0– 开发者快速入门 超级账本Fabric教程(一):超级账本入门 区块链技术基础语言(三十二):Go语言网络编程(下) 区块链技术基础语言(三十一):Go语言网络编程(上) 区块链技术基础语言(三十):Go语言常用工具包(下) 区块链技术语言(二十九)—Go语言常用工具包(上) 区块链技术语言(二十七)——Go语言并发编程(上) 区块链技术语言(二十六)——Go语言异常处理 区块链技术语言(二十五)——面向对象:接口 区块链技术语言(二十四)——Go语言面向对象:匿名组合 区块链技术语言(二十三)——Go语言面向对象:方法
区块链技术语言(二十八)——Go语言并发编程(下)
网鱼 · 2019-03-07 · via 博客园 - 网鱼

本节紧接上一节的内容,主要介绍channel中的有缓冲channel、单方向的channel、定时器,以及select语句在channel中的应用。

3.4 有缓冲的channel

3.4.1 概述

有缓冲的通道(buffered channel)是一种在被接收前能存储一个或者多个值的通道。这种类型的通道并不强制要求goroutine之间必须同时完成发送和接收,通道会阻塞发送和接收动作的条件也不同:只有在通道中没有要接收的值时,接收动作才会阻塞;只有在通道没有可用缓冲区容纳被发送的值时,发送动作才会阻塞。有缓冲的通道和无缓冲的通道之间的最大不同在于:无缓冲通道保证发送和接收的goroutine会在同一时间进行数据交换;有缓冲的通道没有这种保证。图2通过示意图分析了多个goroutine利用有缓冲通道来共享一个值:
a. 第1步,右侧的goroutine正在从通道中接收一个值;
b. 第2步,右侧的这个goroutine独立完成了接收值的动作,而左侧的goroutine正在发送一个新值到通道里;
c. 第3步,左侧的goroutine向通道发送新值,右侧的goroutine正在从通道接收另外一个值。这个步骤里的两个操作既不是同步的,也不会互相阻塞;
d. 第4步,所有的发送和接收都完成,而通道里还有几个值,也有一些空间可以存更多的值。

3.4.2 有缓冲的channel的创建

如果给定了一个缓冲区容量,通道就是异步的。只要缓冲区有未使用空间用于发送数据,或者还包含可以接收的数据,那么其通信就会无阻塞地进行。有缓冲的channel创建格式如下:

示例代码:

3.5 单方向的channel

3.5.1 概述

channel默认双向。既可以向channel里发送数据,也可以从channel里接收数据。但是,要使channel作为参数传递且被单向使用,即只向该channel发送数据,或此channel只接收数据,那么需要对此channel指定方向。

3.5.2 单向channel变量的声明

单向channel变量有两种:一种是只能向channel里发送数据的变量,另一种是只能从channel里接收数据的变量。单向channel变量的声明格式如表2。

注:

a. chan<-表示把数据写入管道;
b. <-chan表示将数据从管道中读取。

3.5.3 channel的转换

普通的channel可以隐式地转换为单向的channel,只接收数据或只发送数据;但是单向的channel不能转换为普通的channel。

示例代码:

四、select

4.1 select语法结构

Go语言关键字select可以监听channel上的数据流动。它的用法与switch语句类似,由select开始一个新的选择块,每个选择条件由case语句来描述。与switch语句可以选择任何可使用相等比较的条件相比, select有比较多的限制,其中最大的一条限制就是每个case语句里必须是一个IO(输入/输出)操作,它的语法结构如下:

4.2 select语句执行顺序

在select语句中,Go语言按顺序从头至尾评估每一个发送和接收的语句:
如果其中任意一条语句可以继续执行(即没有被阻塞),那么就从那些可以执行的语句中任意选择一条来使用。

如果没有一条语句可以执行(即所有的通道都被阻塞),那么有两种可能的情况:第一,如果有default语句,那么就会执行default语句,同时程序的执行会从select语句后的语句中恢复;第二,如果没有default语句,那么select语句将被阻塞,直到至少有一个case语句可以进行下去。

在没有case准备就绪时,可以执行select语句中的default语句,这通常用于防止select语句一直阻塞。

4.3 在select语句中设置超时

当goroutine阻塞时,为避免整个程序进入阻塞,可以在select语句设置超时,具体通过如下方式实现:

示例如下:

参考资料:
https://www.cnblogs.com/tangchuanyang/p/5553434.html
http://www.flysnow.org/2017/04/11/go-in-action-go-goroutine.html
https://studygolang.com/articles/3028