分享
  1. 首页
  2. 文章

Golang协程与通道整理

max2005 · · 5458 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

协程goroutine

不由OS调度,而是用户层自行释放CPU,从而在执行体之间切换。Go在底层进行协助实现
涉及系统调用的地方由Go标准库协助释放CPU
总之,不通过OS进行切换,自行切换,系统运行开支大大降低


通道channel

并发编程的关键在于执行体之间的通信,go通过通过channel进行通信
channel可以认为类似其他OS体系中的消息队列,只不过在go中原生支持,因而易用

消息队列有哪些值得关注的地方?常见问题包括创建、关闭或删除、阻塞、超时、优先级等,golang中也不例外。罗列如下:
可否探测队列是满或空?或者说是否可以不阻塞地尝试读写?
读阻塞和写阻塞时关闭会怎样?
关闭后未读取的消息会被抛弃?
往关闭的channel发送数据或读取数据会怎样?
怎样探测channel的关闭?
两个地方读或写阻塞同一个channel,有没有优先级?
是否可以设定阻塞的超时时间?
阻塞时怎样可以被弹出来?比如某些信号?
事实上,知道存在这些问题并进行分门别类是重要的,但知道这些问题的答案却不紧要,因为一般不会太过古怪,使用时临时试验一下即可。

已知的部分答案:
好像不能不阻塞地尝试读写
关闭会导致退出阻塞(似乎是一个不错的特性)
可以探测关闭
channel本身不能设定超时
了解这些似乎已经足够。


与众不同的地方值得我们重点留意,包括:
除基本读写方式外,还有哪些特别的读写方式?在阻塞、关闭、超时方面又有什么不同?发现了select、range两个关键字
推荐的多通道读
推荐的同步方法
推荐的超时方法



select

select可以实现无阻塞的多通道尝试读写,以及阻塞超时
varc, c1, c2, c3chanint
vari1, i2int

select{
casei1 = <-c1://如果能走通任何case则随机走一个
print("received ", i1," from c1\n")
casec2 <- i2:
print("sent ", i2," to c2\n")
casei3, ok := (<-c3):
ifok {
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(chanbool, 1)
gofunc() {
time.Sleep(1e9)// 这是等待1秒钟
timeout <-true
}()
// 用timeout这个通道作为阻塞超时的出路
select{
case<-ch:
// 处理从ch中读到的数据
case<-timeout:
// 如果case都阻塞了,那么1秒钟后会从这里找到出路
}


range

range可以在for循环中读取channel
Go文档的翻译文是:对于信道,其迭代值产生为在该信道上发送的连续值,直到该信道被关闭。若该信道为 nil,则range表达式将永远阻塞
经过试验,range会阻塞,并且可以通过关闭channel来解除阻塞。

packagemain

import(
"fmt"
)

funcmain() {
ch :=make(chanint)

gofunc() {
fori := 0; i < 10; i++ {
ch <- i
}

}()

forw :=rangech {
fmt.Println("fmt print", w)
ifw > 5 {
//break // 在这里break循环也可以
close(ch)
}
}
fmt.Println("after range or close ch!")
}


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


有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:max2005

查看原文:Golang协程与通道整理

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
5458 次点击
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏