0

在我的代码中有三个并发例程。我尝试简要概述我的代码,

Routine 1 {
do something

*Send int to Routine 2
Send int to Routine 3
Print Something
Print Something*

do something
}

Routine 2 {
do something

*Send int to Routine 1
Send int to Routine 3
Print Something
Print Something*

do something
}

Routine 3 {
do something

*Send int to Routine 1
Send int to Routine 2
Print Something
Print Something*

do something
}

main {
routine1
routine2
routine3
}

我想要这样,当两个之间的代码做某事(两个星号之间的代码)正在执行时,控制流不能转到其他 go 例程。例如,当routine1正在执行两颗星之间的事件(发送和打印事件)时,必须阻塞例程2和3(意味着执行流程不会从例程1转到例程2或3)。完成最后一个打印事件后,执行流程可能会传递给例程 2 或 3。任何人都可以通过指定来帮助我,我该如何实现?是否可以通过 WaitGroup 实现上述规范?任何人都可以通过给出一个简单的例子来告诉我如何使用 WaitGroup 来实现上述指定的例子。谢谢。

注意:可能这是重复的问题。但是,我尝试使用该同步锁定机制,这可能是因为我的代码很大,这就是为什么我无法正确放置锁定解锁的原因,并且它正在造成死锁情况(或者可能是我的方法产生错误)。任何人都可以通过一个简单的程序帮助我,这样我就可以做到这一点。我在这里给出了我的代码的一个简单示例,在这里我想在互斥锁中放置两个打印和发送事件(对于例程 1),因此例程 2 不能中断它。你能帮助我怎么可能。给出了一种可能的解决方案, http ://play.golang.org/p/-uoQSqBJKS给出了错误。

4

2 回答 2

3

你为什么要这样做?

死锁问题是,如果您不允许安排其他 goroutine,那么您的频道发送将无法继续,除非有缓冲。Go 的通道具有有限的缓冲,因此在它们满时发送之前,您最终会遇到耗尽的竞争条件。您可以引入无限缓冲,或者将每个发送放在自己的 goroutine 中,但这又归结为:您为什么要这样做;你想达到什么目的?

另一件事:如果你只想保证*s之间的三组代码互斥,那么可以,你可以使用互斥锁。如果您想确保没有代码中断您的块,无论它在哪里暂停,那么您可能需要使用 runtime.LockOSThread 和 runtime.UnlockOSThread。这些是相当低的级别,您需要知道自己在做什么,而且很少需要它们。如果您希望没有其他 goroutine 运行,则必须使用 runtime.GOMAXPROCS(1),这是当前的默认设置。

于 2011-12-04T05:25:26.107 回答
3

回答你的问题的问题是,似乎没有人了解你的问题到底是什么。我看到您反复询问大致相同的问题,尽管没有取得任何进展。说这话没有冒犯。它试图通过建议以其他人可以理解的方式重新表述您的问题来帮助您。作为一个可能的好副作用,一些问题在以一种可以理解的方式向其他人解释的同时确实解决了自己。我一个人经历过很多次。

另一个提示可能是显式同步和频道通信的可疑组合。这并不意味着设计必然被破坏。它只是不会发生在典型/简单的情况下。再一次,您的问题可能是非典型/非微不足道的。

也许仅使用通道就可以以某种方式重新设计您的问题。实际上,我相信每个涉及显式同步(在 Go 中)的问题都可以在仅使用通道的情况下进行编码。也就是说,确实有些问题很容易用显式同步编写。同样,通道通信虽然便宜,但不如大多数同步原语便宜。但这可以稍后在代码工作时进行处理。如果有人说sync.Mutex的“模式”会明显出现在代码中,那么当代码已经工作并且希望在进行调整时有测试可以观察你的步骤时,应该可以切换到它并且更容易做到这一点.

试着想想你的 goroutines,比如独立代理的代理,它:

  • 独家拥有从频道接收的数据。语言不会强制执行这一点,你必须部署自己的纪律。
  • 不要再触摸他们发送到频道的数据。它遵循第一条规则,但重要到足以明确。
  • 通过数据类型与其他代理(goroutines)交互,这些数据类型封装了整个工作流/计算单元。这消除了您之前在“单元”完成之前获得正确数量的频道消息的困难。
  • 对于他们使用的每个通道,之前必须绝对清楚该通道是否必须是无缓冲的,是否必须为固定数量的项目进行缓冲,或者它是否可能是未绑定的。
  • 不必考虑(知道)其他代理在做什么,而不是从他们那里得到消息,如果代理需要这样做来完成自己的任务 - 这是大局的一部分。

即使使用这么少的经验法则,也有望产生更容易推理并且通常不需要任何其他同步的代码。(我现在有意忽略关键任务应用程序的性能问题。)

于 2011-12-04T10:45:10.913 回答