2 回答
TA贡献1827条经验 获得超7个赞
你为什么要这样做?
死锁问题是,如果您不允许安排其他goroutine,则除非有缓冲,否则您的频道发送将无法进行。Go的频道具有有限的缓冲,因此您在耗尽状态之前就陷入了竞争的局面,然后才被发送出去。您可以引入无限缓冲,也可以将每个发送放入自己的goroutine中,但是又可以归结为:为什么要这样做?您想达到什么目的?
另一件事:如果只希望确保* s之间的三组代码互斥,那么可以使用互斥锁。如果要确保没有代码中断块,无论块在何处被挂起,则可能需要使用runtime.LockOSThread和runtime.UnlockOSThread。这些级别很低,您需要知道自己在做什么,而很少需要它们。希望没有其他goroutine运行,您必须要有runtime.GOMAXPROCS(1),这是当前的默认值。
TA贡献2036条经验 获得超8个赞
回答您的问题的问题在于,似乎没有人了解您的问题的实质。我看到您反复询问大致相同的内容,尽管尚未取得任何进展。这么说并没有冒犯。这是通过建议以其他人可以理解的方式帮助您解决问题的尝试。作为一个可能的好副作用,某些问题确实可以解决,同时可以用一种可以理解的方式向其他人解释。我一个人经历了很多次。
另一个提示可能是显式同步和频道通信的可疑混合。这并不意味着设计必然坏了。它只是在典型/简单的情况下不会发生。再一次,您的问题可能不典型/不平凡。
也许有可能仅使用渠道来重新设计您的问题。实际上,我相信可以在仅使用通道的情况下对涉及显式同步(在Go中)的每个问题进行编码。也就是说,确实可以很容易地通过显式同步编写一些问题。同样,信道通信虽然便宜,却不如大多数同步原语便宜。但这可以在以后的代码运行时得到解决。如果有人说出“ pattern”说出了sync.Mutex将会出现在代码中,那么应该可以切换到它,并且当代码已经可以工作时更容易做到这一点,并希望在进行调整的同时进行测试以观察您的步骤。
尝试像独立代理一样思考您的goroutine,这些代理可以:
独家拥有从通道接收的数据。语言不会强制执行此操作,您必须部署自己的学科。
不要再触摸他们已发送到频道的数据。它遵循第一条规则,但足够重要,必须明确。
通过数据类型与其他代理(goroutine)进行交互,这些数据类型封装了工作流/计算的整个单元。例如,这消除了您之前在“单元”完成之前获得正确数量的通道消息的工作。
对于它们使用的每个通道,必须绝对清楚是否必须取消缓冲该通道,必须为固定数量的项目缓冲该通道或该通道可能未绑定。
如果代理需要自己的信息来完成自己的任务,则不必考虑(了解)其他代理正在做什么,这是更广阔的前景的一部分。
即使使用很少的经验法则,也有望产生出更易于推理且通常不需要任何其他同步的代码。(我现在有意忽略关键任务应用程序的性能问题。)
- 2 回答
- 0 关注
- 179 浏览
添加回答
举报