Go 语言从入门到实战
蔡超
Mobvista 技术副总裁兼首席架构师,前亚马逊(中国)首席软件架构师
48919 人已学习
新⼈⾸单¥59
课程目录
已完结/共 55 讲
第一章:Go语言简介 (4讲)
第二章:基本程序结构 (4讲)
第三章:常用集合 (3讲)
第四章:字符串 (1讲)
时长 16:47
第五章:函数 (2讲)
第六章:面向对象编程 (4讲)
第七章:编写好的错误处理 (2讲)
第八章:包和依赖管理 (2讲)
第九章:并发编程 (7讲)
第十章:典型并发任务 (5讲)
第十一章:测试 (3讲)
时长 11:48
时长 07:12
时长 06:15
第十二章:反射和Unsafe (3讲)
时长 08:18
时长 08:03
第十三章:常见架构模式的实现 (2讲)
第十四章:常见任务 (4讲)
时长 04:27
时长 05:14
第十五章:性能调优 (4讲)
第十六章:高可用性服务设计 (5讲)
Go 语言从入门到实战
登录|注册
留言
8
收藏
沉浸
阅读
分享
手机端
回顶部
当前播放: 26 | 多路选择和超时
00:00 / 00:00
高清
  • 高清
1.0x
  • 2.0x
  • 1.5x
  • 1.25x
  • 1.0x
  • 0.75x
  • 0.5x
网页全屏
全屏
00:00
付费课程,可试看
01 | Go语言课程介绍
02 | 内容综述
03 | Go语言简介:历史背景、发展现状及语言特性
04 | 编写第一个Go程序
05 | 变量、常量以及与其他语言的差异
06 | 数据类型
07 | 运算符
08 | 条件和循环
09 | 数组和切片
10 | Map声明、元素访问及遍历
11 | Map与工厂模式,在Go语言中实现Set
12 | 字符串
13 | Go语言的函数
14 | 可变参数和defer
15 | 行为的定义和实现
16 | Go语言的相关接口
17 | 扩展与复用
18 | 不一样的接口类型,一样的多态
19 | 编写好的错误处理
20 | panic和recover
21 | 构建可复用的模块(包)
22 | 依赖管理
23 | 协程机制
24 | 共享内存并发机制
25 | CSP并发机制
26 | 多路选择和超时
27 | channel的关闭和广播
28 | 任务的取消
29 | Context与任务取消
30 | 只运行一次
31 | 仅需任意任务完成
32 | 所有任务完成
33 | 对象池
34 | sync.pool对象缓存
35 | 单元测试
36 | Benchmark
37 | BDD
38 | 反射编程
39 | 万能程序
40 | 不安全编程
41 | 实现pipe-filter framework
42 | 实现micro-kernel framework
43 | 内置JSON解析
44 | easyjson
45 | HTTP服务
46 | 构建RESTful服务
47 | 性能分析工具
48 | 性能调优示例
49 | 别让性能被锁住
50 | GC友好的代码
51 | 高效字符串连接
52 | 面向错误的设计
53 | 面向恢复的设计
54 | Chaos Engineering
55 | 结课测试&结束语
登录 后留言

全部留言(8)

  • 最新
  • 精选
Kvicii.Y
例子中的是buffer channel,为什么不能是channel呢?50毫秒内返回了也就不会阻塞了,应该正常输出呀,但是为什么一直输出超时呢?是不是channel会一直阻塞,即使取到了数据也是阻塞?

作者回复: 如果结果在超时后才返回,就没有携程从channel中获取数据,这是如果不采用buffer channel,数据产生者携程就会一直阻塞,导致携程泄漏。 我的例子中给的等待是500ms,而超时时100ms,你可以把等待改成50ms,就不会超时了。

2020-03-13
4
张仁杰
Select多渠道选择,既然case都处于阻塞等待状态,为什么会走default呢?

作者回复: 这个并不是从上到下顺序执行的,当所有的case处于阻塞状态,就会走default分支

2020-09-03
2
Van
``` func AsyncServices() chan int { ch := make(chan int, 1) go func() { time.Sleep(time.Millisecond * 200) // 不管有没有这个走的都是default ch <- 1 }() return ch } func TestSelect(t *testing.T) { select { case ch := <-AsyncServices(): t.Log(ch) case <-time.After(time.Millisecond * 100): t.Error("Time out.") default: t.Log("Receive nothing.") } } ``` select 使用了default 之后为什么超不超时走的都是default 分支呢

作者回复: 如果有多个 case 都可以运行,Select 会随机公平地选出一个执行。其他不会执行。 否则: 如果有 default 子句,则执行该语句。 如果没有 default 子句,select 将阻塞,直到某个通信可以运行;Go 不会重新对 channel 或值进行求值。

2020-02-29
5
2
hughieyu
老师您好,多个生产者的情况下,如何通知生产者消息已经发完了呢?是不是就只能通过计次的形式来处理了?另外channel如果不关闭会有什么问题吗?channel实际上也是共享内存的模型吧,没有buffer的channel应该就是同步队列模型,有buffer的channel应该就是阻塞队列模型,channel解决的问题就是怕让生产者和消费者之间松耦合,这个实际上也对应于java里面的并发队列呗,只是作为语言特征出现,用起来会方便不少,这样理解对吗?

作者回复: 1. 发送完毕可以通过close来通知接收者。 2. channel不关闭不会有问题,它不是核心句柄(如:文件,socket) 3. channel的确用来解偶生产者和消费者。

2019-09-13
1
kaizen
加上default,也就意味着,如果在运行selcet时,case中的channel都没有message时,则会直接走default那条路。 但是如果case中都完成了,随机选择一条路走(老师,感觉没有什么场景需要这种随机性吧,感觉很不幂等耶)

作者回复: 有的。例如,并行执行多个查询,只要其中一个返回即可。

2020-04-13
2
海盗船长
请教老师 多路选择除了设置超时时间 还可以用在哪里典型的场景?

作者回复: 常见的用途还包括,多个并行任务的返回等待。可以参见后面的典型并发任务的章节

2020-01-12
right-chen
留言区也能学习不少 func TestSelect(t *testing.T) { //设置字符串类型的通道,容量10 chan_msg := make(chan string) chan_msg2 := make(chan string) go func() { time.Sleep(1 * time.Second) chan_msg <- "finish" }() go func() { time.Sleep(1 * time.Second) chan_msg2 <- "finish" }() /** select 语句中,case不依赖代码书写顺序。 如果case中有1个有消息时,其他case/default则不会执行。 如果case中有多个消息时,随机任选1个进行执行,其他不会执行 如果所有case都没有消息时,同时含有defalut分之,则会走default分之 如果所有case都没有消息时,没有default分之,则会阻塞等待case中返回消息继续执行。 */ time.Sleep(1 * time.Second) select { case <-chan_msg: t.Log("work1") case <-chan_msg2: t.Log("work2") case <-time.After(time.Millisecond * 5000): t.Error("time out") default: t.Log("default") } }
2022-08-07
escray
select 多路选择和其他语言中的 switch 比较像( Go 语言中似乎没有 Switch ?),但是从执行顺序(随机选择)和 default 的用法来说有很大的差别。 select 很像 switch,每个 Case 后面跟的是阻塞事件,从 channel 上等待消息。 执行到 select 的时候,只要任何 case 后面的任何一个等待渠道,阻塞事件处于非阻塞状态,就是 channel 中有一个消息,那么就会执行后续的代码 但是不能依赖 case 的顺序。 一定要看留言中的回复。 在 @Van 的留言里面,select 会不等到超时就执行 default 子句,very tricky。 如果有多个 case 都可以运行,Select 会随机公平地选出一个执行。其他不会执行。 否则,如果有 default 子句,则执行该语句;如果没有 default 子句,select 将阻塞,直到某个通信可以运行。
2021-04-10
1
收起评论