Golang实践经验和教训(15)

缺少条件检查

在不能仅依靠锁独占性的情况下 , 需要进行条件检查 。 想象一个经典的场景 , 有一个生产者和多个消费者使用一个共享队列 。 生产者可以将一项添加到队列中 , 并唤醒所有消费者 。 唤醒调用意味着队列中有一些数据可用 , 并且由于队列是共享的 , 因此必须通过锁来同步访问 。 每个消费者都有机会遇到锁;但是 , 仍然需要检查队列中是否有项目 。 需要进行条件检查 , 因为当遇到锁时还不知道队列状态 。

在HALO中 , 超时处理程序收到了来自计时器到期的\"唤醒\"调用 , 但是它仍需要检查是否已向其发送了取消信号 , 然后才能继续执行回调 。

死锁

当一个线程被卡住 , 无限期地等待一个信号唤醒时 , 就会发生这种情况 , 但是这个信号永远不会到达 。

在HALO中 , 由于多次发送调用到一个非缓冲且阻塞的通道导致死锁 , 这样仅在同一通道上完成接收后 , 发送调用才会返回 。 超时线程循环迅速在取消通道上接收信号;但是 , 在接收到第一个信号后 , 它将中断环路 , 并且再也不会从该通道读取数据 。 其余的调用将会被卡住 。

推荐阅读