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

27 | channel的关闭和广播

蔡超
Mobvista技术副总裁兼首席架构师,前亚马逊(中国)首席软件架构师
55讲 55课时,约700分钟6221
单独订阅¥129
2人成团¥99
5
本节摘要
展开
登录 后留言

精选留言(12)

  • 面朝大海春暖花开
    开始有点困扰,如果channel里的数据没有取完,这时producer关闭了channel,receiver能继续取数据么?
    然后实验了一下:发现当receivers从channel取完了数据,producer的colse(channel)才会被执行,即close(channel)会阻塞至channel中数据全部被取完。
    不知道对不对,请老师指点。多谢!
    2019-04-01
    1
  • Harry陈祥
    老师您好。
    传参 chan的时候,指针传参和值传参,看起来好像都可以work,而且复用的还是同一个通道。

    那对于chan的值传参,copy的是什么?

    作者回复: 这个在前面的课程中讲到过,chan是一个结构,这个结构在传递时是被复制的,其中的指针成员也会被复制到新的chan中,所以新旧两个chan会指向同一个内存区域

    2019-03-24
    1
  • 我姓蔡。
    对于通道的okidiom,ok我更愿意理解为是否有数据可以接收,对于同步通道来说,接发都是阻塞的,接收数据不阻塞了要么是有一端发送了数据,要么是通道close了,所以对于同步通道ok为false,那么就是通道关闭了,对于异步通道来说,通道close了,但是通道中还有数据存在,这个时候接收ok还是为true,只有当没有数据可以接收了,ok才为false。
    对于closed和nil的通道:
    1.对于closed的通道,发送数据会panic
    2.对于closed的通道,同步通道会读出零值,异步通道如果有缓存数据读出缓存数据,没有缓存数据读出零值
    3.对于nil通道,读和写都会阻塞,可以利用这一点,在通道多路选择的时候,将读完数据的通道置空,判断所有通道都为nil之后才退出。
    2019-11-05
  • 碧雪天虹
    消费者可以通过 data,ok<-ch 来判断通道是否关闭, 生产者如何判断通道是否关闭?

    func TestCloseChannel(t *testing.T) {
    var wg sync.WaitGroup
    ch := make(chan int)
    dataProducer(ch, &wg)
    dataReceiver(ch, &wg)
            // 已经关闭通道, 生产者如何判断
    close(ch)
    wg.Wait()
    }

    作者回复: 通道应该由生产者来关闭,在关闭的channel上发送数据程序会panic

    2019-10-21
  • 欢喜哥
    老师,请教一个问题,如果做爬虫程序,其实程序启动就是死循环,初始化channel容量10个,有新数据就添加到channel里,然后一直不关闭,应该也不会有问题吧

    作者回复: 这部分不会有问题。

    2019-09-26
  • 虢国技酱
    跟着老师一起手动敲代码,越瞧越来劲
    2019-08-08
  • 小马
    func TestCloseChannel(t *testing.T) {
    var wg sync.WaitGroup
    ch := make(chan int)

    wg.Add(1)
    dataProducer(ch, &wg)
    wg.Add(1)
    dataReceiver(ch, &wg)
    wg.Add(1)
    dataReceiver(ch, &wg)
    wg.Add(1)
    dataReceiver(ch, &wg)
    wg.Wait()
    }

    想知道,为什么后面的两个 dataReceiver 也能得到数据, 难道这三个dataReceiver不是串行执行的吗?我的理解是第一个 dataReceiver 会把 dataProducer 产生的所有数据都读完 才退出。

    作者回复: 虽然,语句是串行的,是线程的调度不是

    2019-07-09
  • 田佳伟
    老师,当发送操作在执行的时候发现空的通道中,正好有等待的接收操作,那么它会直接把元素值复制给接收方,实际是这样的吗

    作者回复: 实际上和方法调用的直接传递复制是不同的,还是通过chan来完成的

    2019-06-25
  • Geek_669c0b
    wg是不是要设置一下超时时间呢

    作者回复: waitgroup 方法是没有timeout可以设置的。你可以通过后面课程介绍的取消任务相关的内容自己实现一个有超时的等待(参见select部分内容)

    2019-06-14
  • Steven Fung
    func serviceOne() string {
    time.Sleep(time.Millisecond * 50)
    return "service 1 done"
    }

    func channelserviceone_2nd() chan string {
    retCh := make(chan string, 1)
    go func() {
    ret := serviceOne()
    fmt.Println("returned result.")
    retCh <- ret
    fmt.Println("service exited.")
    }()
    return retCh
    }

    func TestSelect(t *testing.T) {
    select {
    case ret := <-channelserviceone_2nd():
    t.Log(ret)
    case <-time.After(time.Millisecond * 49):
    t.Log("time out")
    }
    }

    Output:
    === RUN TestSelect
    returned result.
    service exited.
    --- PASS: TestSelect (0.05s)
        /Users/stevenfung/Documents/code/go/src/github.com/CrazyPassion/go/helloworld/test/goroutine/goroutine_test.go:115: time out
    PASS
    ok github.com/CrazyPassion/go/helloworld/test/goroutine 0.058s
    Success: Tests passed.
    老师,请教下这个问题,这个想不明白。按说serviceOne等待是50ms,49ms会超时,觉得应该看不到channelserviceone_2nd里面的打印,但是现在可以看到,并且也看到了超时的打印,这个是为什么?

    作者回复: 这是因为你用的是buffered chan他是非阻塞的。所以只要外面的主协程在退出前能有时间让他运行完,他就可以输出。
    你可以在TestSelect最后退出前加一个sleep 1秒,你就会发现更短的timeout一样会输出那些信息

    2019-04-05
  • 忽然之间
    type MyChan struct {
    Chid int
        Msg string
    }

    func dataProducer1(ch chan MyChan, wg *sync.WaitGroup) {
    go func() {
    for i := 0; i < 10; i++ {
    ch <- MyChan{i, "msg"}
    }
    close(ch)
    wg.Done()
    }()
    }

    func TestCloseChannel1(t *testing.T) {
    var wg sync.WaitGroup
    ch := make(chan MyChan)
    wg.Add(1)
    dataProducer1(ch, &wg)
    wg.Add(1)
    dataReceiver1(ch, &wg)
    wg.Wait()
    }

    先模仿老师的代码。
    2019-03-20
  • Gary
    channel可以放自定义类型吗?

    作者回复: 可以的

    2019-03-20
收起评论
看过的人还看
左耳听风

陈皓  网名“左耳朵耗子”,资深技术专家,骨灰级程序员

108讲 | 40800 人已学习

拼团 ¥199 原价 ¥299
趣谈网络协议

刘超  网易研究院云计算技术部首席架构师

51讲 | 40024 人已学习

拼团 ¥79 原价 ¥99
Go语言核心36讲

郝林  《Go并发编程实战》作者,前轻松筹大数据负责人

54讲 | 24286 人已学习

拼团 ¥79 原价 ¥99
MySQL实战45讲

林晓斌  网名丁奇,前阿里资深技术专家

48讲 | 44076 人已学习

拼团 ¥79 原价 ¥99