• 蓝士钦
    2019-03-27
    一楼[ZY]的留言 “当一个channel满了之后 无法继续插入 会报错,但是放到协程里面却可以在满了之后 继续插入数据 为什么呢?”
    我的理解是这样的:
    1.你的代码里有生产者和消费者,使用for循环开启了10个协程,channel还没满的时候就被消费者提前消费掉了,其实只能添加10数据,可以把消费者去掉, 并且加上日志打印:代码如下:
        var wg sync.WaitGroup
        num := 10
        ch := make(chan int, num)
        for i := 0; i < 1000; i++ {
            wg.Add(1)
            go func(i int) {
                ch <- i    // 协程满后会阻塞,导致无法执行厦门的wg.Done()导致死锁报异常
                fmt.Printf("执行协程:%d\n",i)
                wg.Done()
            }(i)
            wg.Wait()
        }

    2.可以在一个协程里循环添加超过channel大小的数据,依旧会阻塞
    func TestChannelPush(t *testing.T) {
        ch := make(chan int, 10)
        var wg sync.WaitGroup
        wg.Add(1)
        pushChannel(ch,&wg)
        wg.Wait()
    }

    func pushChannel(ch chan int, wg *sync.WaitGroup) {
        go func() {
            for i := 0; i < 100; i++ {
                ch <- i
            }
            wg.Done()
        }()
    }

    因为这里用了WaitGroup,所以会有死锁,实际上是会阻塞。
    展开
    
     4
  • 「ZY」
    2019-03-27
    蔡老师您好
    这节课您里面讲到 当一个channel满了之后 无法继续插入 会报错
    但是放到协程里面却可以在满了之后 继续插入数据 为什么呢?
    申请的时候是10个 插入11个

    num := 10
    ch := make(chan int, num)
    for i := 0; i < num+1; i++ {
        go func(i int) {
            ch <- i
        }(i)
    }

    total := 0
    for i := 0; i < num+1; i++ {
        total += <-ch
    }
    fmt.Println("for total-------", total)
    展开
    
     3
  • 肥low
    2019-03-28
    感觉还是带着写代码比较容易理解
    
     2
  • 蓝士钦
    2019-03-27
    补充一下ZY的留言,channel大小虽然只有10,for循环开启11个协程往channel添加数据,但是因为协程和主程序是异步的所以看不出阻塞,因为后面的消费者程序把channel的数据消费了,所以上面可能存在的阻塞又通了,一边生产一边消费,MQ经常堆包也是类似的情况,在主机内存空间有限的情况下如果消费者处理消息的速度比生产者慢,就有可能堆包,严重的就阻塞。
    
     2
  • 纛下靥狗
    2019-04-04
    蔡老师您好
    在对象池一课我参考之前的课程使用unsafe.Pointer在不放回的情况下打出了每个对象的地址,发现他们都是一样的, 这个时候结构体里没有定义任何成员。
    我把NewObjPool的初始化对象改成了每个都赋予一个id int子成员的情况下10个对象打印出的地址就不同了(预期)
    后来在网上查阅发现这个是空结构体,用unsafe.Sizeof发现占用的大小为0,所以每次初始化的位移就是0,所以每个对象的地址都是相同。
    而如果增加一个int成员的话,Size就会变成8,然后地址的位移也是8.

    另外老师github上的代码没有更新了最近。。。
    展开

    作者回复: 很赞!在可执行的代码中学习!
    代码我会尽快提交,并通知平台更新。

    
     1
  • 田佳伟
    2019-07-18
    老师,假如我用对象池当做MySQL连接池用的话,我创建100个连接,然后在并发情况下连接池空了,这个时候后续的query只能等待或者timeout吗?还有没有别的更好的方案

    作者回复: 较常见的,还可以降级处理,超时后直接从缓存返回历史数据或返回默认数据。

    
    
  • 帅
    2019-04-01
    老师你好,time out在项目中的正确处理是什么?应该不是只报个错,然后输出timeout吧。。

    作者回复: 后面的高可用性课程会讲。继续看哦

    
    
  • GeekConsole.net
    2019-03-28
    这就结束啦,等等等更新
    
    
  • 「ZY」
    2019-03-28
    感谢 蓝士钦 的回答
    确实是这样的 带长度的channel 在满了之后 会阻塞
    没满的时候不会阻塞
    
    
我们在线,来聊聊吧