并发执行并发Go例程的问题

时间:2011-12-04 04:46:42

标签: concurrency go concurrent-programming goroutine

在我的代码中有三个并发例程。我试着简要介绍一下我的代码,

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
}

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

注意:这可能是this的重复问题。我尝试使用这种同步锁定机制,但是,可能是因为我有一个很大的代码,这就是为什么我无法正确锁定解锁,并且它正在创建死锁情况(或者可能是我的method是{{3 }})。任何人都可以通过一个简单的程序帮助我,因此我可以做到这一点。 我给出了我的代码error producing的一个简单示例。在这里,我想放置两个打印件并在互斥锁中发送事件(例程1),因此例程2不能中断它。你能帮我一下吗?一个可能的解决方案, 导致错误的here

2 个答案:

答案 0 :(得分:3)

你为什么要这样做?

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

另一件事:如果您只想确保在* s之间互斥三组代码,那么是的,您可以使用互斥锁。如果要确保 no 代码中断您的块,无论它被挂起的位置如何,那么您可能需要使用runtime.LockOSThread和runtime.UnlockOSThread。这些都是相当低的水平,你需要知道你在做什么,而且很少需要它们。你想要没有其他goroutines运行,你必须有runtime.GOMAXPROCS(1),这是目前的默认值。

答案 1 :(得分:3)

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

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

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

尝试考虑你的goroutines,如独立代理人:

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

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