Golang协程与通道整理

协程goroutine

不由OS调度,而是用户层自行释放CPU,从而在执行体之间切换。Go在底层进行协助实现

涉及系统调用的地方由Go标准库协助释放CPU

总之,不通过OS进行切换,自行切换,系统运行开支大大降低

通道channel

并发编程的关键在于执行体之间的通信,go通过通过channel进行通信

channel可以认为类似其他OS体系中的消息队列,只不过在go中原生支持,因而易用

消息队列有哪些值得关注的地方?常见问题包括创建、关闭或删除、阻塞、超时、优先级等,golang中也不例外。罗列如下:

可否探测队列是满或空?或者说是否可以不阻塞地尝试读写?

读阻塞和写阻塞时关闭会怎样?

关闭后未读取的消息会被抛弃?

往关闭的channel发送数据或读取数据会怎样?

怎样探测channel的关闭?

两个地方读或写阻塞同一个channel,有没有优先级?

是否可以设定阻塞的超时时间?

阻塞时怎样可以被弹出来?比如某些信号?

事实上,知道存在这些问题并进行分门别类是重要的,但知道这些问题的答案却不紧要,因为一般不会太过古怪,使用时临时试验一下即可。

已知的部分答案:

好像不能不阻塞地尝试读写

关闭会导致退出阻塞(似乎是一个不错的特性)

可以探测关闭

channel本身不能设定超时

了解这些似乎已经足够。

与众不同的地方值得我们重点留意,包括:

除基本读写方式外,还有哪些特别的读写方式?在阻塞、关闭、超时方面又有什么不同?发现了select、range两个关键字

推荐的多通道读

推荐的同步方法

推荐的超时方法

select

select可以实现无阻塞的多通道尝试读写,以及阻塞超时

var c, c1, c2, c3 chan int

var i1, i2 int

select {

case i1 = <-c1: //如果能走通任何case则随机走一个

print( "received ", i1, " from c1\n" )

case c2 <- i2:

print( "sent ", i2, " to c2\n" )

case i3, ok := (<-c3):

if ok {

print( "received ", i3, " from c3\n" )

} else {

print( "c3 is closed\n")

}

default: // 如果case都阻塞,则走default,如果无default,则阻塞在case

// default中可以不读写任何通道,那么只要default提供不阻塞的出路,就相当于实现了对case的无阻塞尝试读写

print( "no communication\n")

}

实现阻塞超时的方法是,只要不给default出路,而在case中实现一个超时

timeout := make (chan bool, 1)

go func () {

time.Sleep(1e9) // 这是等待1秒钟

timeout <- true

}()

// 用timeout这个通道作为阻塞超时的出路

select {

case <-ch:

// 处理从ch中读到的数据

case <-timeout:

// 如果case都阻塞了,那么1秒钟后会从这里找到出路

}

range

range可以在for循环中读取channel

Go文档的翻译文是:对于信道,其迭代值产生为在该信道上发送的连续值,直到该信道被关闭。若该信道为 nil,则range表达式将永远阻塞

经过试验,range会阻塞,并且可以通过关闭channel来解除阻塞。

package main

import (

"fmt"

)

func main() {

ch := make( chan int )

go func () {

for i := 0; i < 10; i++ {

ch <- i

}

}()

for w := range ch {

fmt.Println( "fmt print" , w)

if w > 5 {

//break // 在这里break循环也可以

close(ch)

}

}

fmt.Println( "after range or close ch!" )

}

Golang的并发编程还有其他细节,但以上是最主要脉络。

原文发布于微信公众号 - Golang语言社区(Golangweb)

原文发表时间:2017-05-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏沈唁志

API接口开发简述示例

2162
来自专栏JAVA高级架构

如何实现大型网站架构设计的负载均衡

负载均衡 (Load Balancing) 负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处...

47210
来自专栏finleyMa

(转) 网站统计中的数据收集原理及实现

原文地址:http://blog.codinglabs.org/articles/how-web-analytics-data-collection-syste...

1801
来自专栏崔庆才的专栏

付费代理的使用

9174
来自专栏腾讯移动品质中心TMQ的专栏

Windows开机过程和测试方法探索

用户会经常抱怨自从安装自己的应用后,电脑开机变慢,到底是系统的原因还是应用的原因,为了了解这里的问题,探秘了下windows的开机过程和测试方法。 一、开机过...

25710
来自专栏Python小屋

Python爬虫系列:使用selenium+Edge查询指定城市天气情况

话说,国外有个网站http://openweathermap.org/可以免费查询指定城市的当前天气情况: ? 那是不是可以写个爬虫程序,自动调用网站的功能来...

3126
来自专栏Timhbw博客

Windows下iOS开发环境搭建教程

2016-06-1513:59:42 发表评论 2,027℃热度 1.下载工具 2.安装基本文件 3.开始主要步骤 4.总结 目录 可能许多初学者并没...

1K8
来自专栏Linyb极客之路

分布式事务的实现原理

事务是数据库系统中非常有趣也非常重要的概念,它是数据库管理系统执行过程中的一个逻辑单元,它能够保证一个事务中的所有操作要么全部执行,要么全不执行;在 SOA 与...

1393
来自专栏CSDN技术头条

饿了么Influxdb实践之路

作者 | 刘平 文章来源GitChat,CSDN独家合作发布,查看交流实录:http://gitbook.cn/books/59428f6f7e850f039...

1.3K6
来自专栏无题

秒杀系统解决方案

从架构、产品、前端、后端四个层面针对秒杀场景(可以扩展到所有高并发场景)分别总结了一些解决方案。 要点总结: 1.架构:扩容,业务分离,数据分离 2.产品:下...

4374

扫码关注云+社区