• peison
    2022-04-15
    请问计数信号量的例子中,因为jobs的容量是10,这里执行的循环不会导致阻塞,close(jobs) 应该会被执行到,那么下面的for range为什么不会终止,而可以继续运行? go func() { for i := 0; i < 8; i++ { jobs <- (i + 1) } close(jobs) }()

    作者回复: 好问题! channel内部数据是排队的,即便被close,依然可以从closed channel中读取到尚未被消费的元素,直到没有可读的元素为止,才真正会变成closed状态。没数据后,如果再读就会得到元素类型的零值了, 对于没数据且closed状态的channel,for range会终止。

    共 5 条评论
    20
  • 张申傲
    2022-02-20
    这节课信息量有点大,需要多看几遍好好消化。请问老师一个问题:如果程序中没有手动 close channel,那么 channel 会在什么时候关闭呢?是否需要借助 defer 去释放 channel 资源呢?

    作者回复: channel一旦没有人引用了,就会被gc掉,不关闭也ok。但是如果有goroutine一直在读channel,那么channel一直存在,不会关闭。直到程序退出。

    
    12
  • ibin
    2022-01-12
    白老师,你好,下面这段可以模拟close(groupSignal) for i := 0;i < 5; i++ { groupSignal<-signal(struct{}{}) } 为什么close(groupSignal) 可以给每个groupSignal都发送了{}

    作者回复: close一个channel后,所有阻塞在这个channel接收操作的goroutine都会收到通知,这是Go语言的channel语义就这么定义的。

    共 4 条评论
    10
  • 木木
    2022-03-18
    go的并发原语选择真的是非常精炼:简洁又强大,一个ch就负责了线程通信、同步的多种功能;一个select又实现了对阻塞、非阻塞的控制以及事件循环模式。

    作者回复: 👍

    
    7
  • airmy丶
    2022-05-18
    请问下老师: 为什么 "1 对 n 的信号通知机制" 这个例子中,wg.Wait() 一定需要新起一个协程执行呢?而且在本地测试确实只能在新的协程中执行才不会报错,否则会报出: goroutine x [chan receive] 这样的错误。

    作者回复: Wait方法的语义就是等待例子中for循环创建的所有子goroutine,直到每个子goroutine都调用完wg.Done才返回。如果不再一个新goroutine执行,wg.Wait就会阻塞住main goroutine,这也将导致后续所有goroutine都阻塞住,然后go运行时检测到所有goroutine都阻塞住了,于是报错退出。

    共 2 条评论
    6
  • 瓜牛
    2022-04-20
    为啥有时需要手动调用close关闭channel,有时又不需要?

    作者回复: 首先明确一点:channel如果不close,也不会存在资源泄露的问题。 是否需要close channel完全看需要。 至于如何知道何时需要,看文中对close channel的语义的描述,以及如何基于这种语义的一些妙用。

    共 2 条评论
    5
  • 罗杰
    2022-01-12
    这节课比较绕,要静下心好好学习

    作者回复: 👍

    
    4
  • 怎么睡才能做这种梦
    2023-03-06 来自湖北
    另外,select 语句中,如果有多个 case 同时都没有阻塞的话,会随机选择一个 case

    作者回复: 👍

    
    3
  • Unknown element
    2022-11-20 来自北京
    老师我看makechan的源码发现分配内存的时候分了3种情况: 1. 缓冲区大小=0 2. 元素类型不是指针 3. 元素类型包含指针 我想问下为什么2和3要分成两种情况呢?我看区别好像是调用 mallocgc 时第二个参数不一样,但是mallocgc 的源码我就看不懂了。。。希望老师可以简单解释下 谢谢老师~

    作者回复: 如果channel中的元素大小为0,那就不需要额外分配缓存(buf); 如果元素类型中不含有指针,那么buf就和hchan一起分配(将来也和hchan一起释放),减少一次heap mem分配。GC只扫描hchan就ok了。 如果元素类型包含指针,那么hchan和hchan.buf单独分配内存,GC分别扫描hchan和buf中的元素。

    
    3
  • 每天晒白牙
    2022-07-20
    感觉只发送channel和只接收channel类型定义符号,交换一下更好理解,也更形象吧 make(chan<- int, 1) 这个代表只接收 make(<-chan int, 1) 这个代表只发送

    作者回复: 由于箭头都是向左的,即<-,所以我区分只发送和只接收型的channel的tip是以 chan这个关键字为中心,将chan关键字看成一个“管子”。当<-在chan的右边,即chan <- 好似向管子里写,这样就是只发送型。当<-在chan的左边,即<- chan ,好似从管子里取,这样就是只接收型。

    共 2 条评论
    3