3 回答
TA贡献1111条经验 获得超0个赞
通常,不要陷入认为更大的缓冲区可以修复死锁的陷阱。这种方法可能在某些特定情况下有效,但通常并非如此。
死锁最好通过了解 goroutine 如何相互依赖来解决。本质上,您必须消除相互依赖的通信循环。非阻塞发送的想法(参见@izca 的回答)是一种有用的技巧,但不是唯一的技巧。
有大量关于如何避免死锁/活锁的知识。其中大部分来自奥卡姆在 80 年代和 90 年代流行的日子。有一些来自诸如 Jeremy Martin(无死锁并发系统的设计策略)、Peter Welch(高级范式)等人的特别珍宝。
客户端-服务器策略很简单:将您的 Go 例程网络描述为一组通信服务器及其客户端;确保网络图中没有循环 => 消除了死锁。
I/o-par 是一种形成 Go-routines 的环和环的方法,这样结构内就不会出现死锁;这就是循环特定情况下是允许的,但行为方式一般无死锁的方式。
所以,我的策略是首先减少缓冲区大小,考虑发生了什么,修复死锁。然后,根据基准重新引入缓冲区以提高性能。死锁是由通信图中的循环引起的。打破循环。
TA贡献2080条经验 获得超4个赞
您的节目陷入僵局,因为您的频道已满。
您的频道大小为 1。然后调用wg.Wait()
.. 等待调用5 个函数。现在,一旦您到达err3
.. rand == 3
,因此您的频道会传递错误。
此时,您的频道已满,您只勾选了 3 个等待组项目。
err4
使用值 3 .. 调用它也想在您的频道上放置错误。此时,它会阻止 - 因为您的频道已满并且没有从中弹出任何内容。
所以你的主要 goroutine 会阻塞,因为你的等待组永远不会完成。
修复确实是使您的通道缓冲区更大。这样,当错误试图放置在通道上时 - 它不会阻塞,并且您的等待组有机会勾选它的所有项目。
- 3 回答
- 0 关注
- 175 浏览
添加回答
举报