当前位置: 首页 > 面试题库 >

并发Goroutine互斥

茅高卓
2023-03-14
问题内容

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

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
}

我希望在html" target="_blank">执行两个代码之间的某些操作(两个星号之间的代码)时,控制流一定不能进入其他goroutine。例如,当例程1正在执行两颗星之间的事件(发送和打印事件)时,例程2和3必须被阻止(执行的平均流量不会从例程1传递到例程2或3)。在完成上一个打印事件后,执行流程可能会传递到例程2或3。有人可以通过指定来帮助我,我该如何实现?是否可以通过WaitGroup来实现上述规范?任何人都可以通过举一个简单的示例向我展示如何使用WaitGroup来实现上面指定的示例。谢谢。

注意:我提供两种发送和两种打印方式,实际上有很多发送和打印方式。


问题答案:

如果我正确理解了它,那么您想要的是防止同时执行每个功能的某些部分和其他功能。下面的代码执行此操作:fmt.Println在其他例程正在运行时,行不会发生。这就是发生的情况:当执行到达打印部分时,它将等待直到其他例程结束(如果它们正在运行),并且在执行此打印行时,其他例程将不会启动并等待。我希望这就是您想要的。如果我对此有误,请纠正我。

package main

import (
    "fmt"
    "rand"
    "sync"
)

var (
    mutex1, mutex2, mutex3 sync.Mutex
    wg sync.WaitGroup
)

func Routine1() {
    mutex1.Lock()
    // do something
    for i := 0; i < 200; i++ {
        mutex2.Lock()
        mutex3.Lock()
        fmt.Println("value of z")
        mutex2.Unlock()
        mutex3.Unlock()
    }
    // do something
    mutex1.Unlock()
    wg.Done()
}

func Routine2() {
    mutex2.Lock()
    // do something
    for i := 0; i < 200; i++ {
        mutex1.Lock()
        mutex3.Lock()
        fmt.Println("value of z")
        mutex1.Unlock()
        mutex3.Unlock()
    }
    // do something
    mutex2.Unlock()
    wg.Done()
}

func Routine3() {
    mutex3.Lock()
    // do something
    for i := 0; i < 200; i++ {
        mutex1.Lock()
        mutex2.Lock()
        fmt.Println("value of z")
        mutex1.Unlock()
        mutex2.Unlock()
    }
    // do something
    mutex3.Unlock()
    wg.Done()
}

func main() {
    wg.Add(3)
    go Routine1()
    go Routine2()
    Routine3()
    wg.Wait()
}

更新
:让我在这里解释这三个互斥锁:一个互斥锁,如文档所述:“互斥锁”。这意味着当您调用Lock互斥锁时,如果其他人已锁定相同的互斥锁,则代码仅在此处等待。在您致电后Unlock,被阻止的代码将立即恢复。

在这里,我通过在函数的开头锁定互斥锁并将其解锁来将每个函数置于自己的互斥锁中。通过这种简单的机制,您可以避免与这些功能同时运行所需的任何代码部分。例如,在您想要拥有运行时不应该运行的代码的任何地方Routine1,只需mutex1在该代码的开头锁定并在末尾解锁即可。这就是我在Routine2和中的适当行中所做的Routine3。希望能澄清一些事情。



 类似资料:
  • 问题内容: 有人可以提供goroutine返回的澄清值。从goroutine返回的值是否已存入抵押。 例如: 我们是否应该避免在go例程中避免返回值? 问题答案: 快速查看一下组装输出显示 该函数确实将其结果存储到堆栈中 因此,当从goroutine调用它时,它会将结果存储到堆栈中。但是,这是一个新的堆栈,当goroutine结束时,该堆栈会被破坏,因此无法获取返回值。 但是,无法检索这些结果。

  • 问题内容: 有一个检查玩家是否在线,并执行状态变更知道他的ID。这必须同时从多个goroutine中完成。 现在,我计划使用streamrail的并发映射,但是常规映射和使用通道的同步又如何呢? 在Go中应该始终首选它吗? 在某些情况下应该首选吗? 他们基本上只是完成同一件事的两种方法吗? 顺便说一句,我知道口号: 不通过共享内存进行通信通过通信共享内存 但是在stdlib中有锁定机制,而在文档中

  • 我试图对goroutines做一个循环,它接受一个接收字符串的通道,每次接收它时,它都应该将值追加到另一个字符串。只有在所有goroutine结束时(goroutine计数应该是传入的的长度),代码才应该继续。

  • 问题内容: 在他对以下问题的回答中:Windows的Golang行为不稳定?建议用户@distributed锁定/同步并发goroutine上对共享变量的访问。 我怎样才能做到这一点? 有关此问题的更多信息: 我获得了同时在多个goroutines 上运行的代码(带有闭包的返回函数): 看起来IO功能很费时间,结果我得到了这种输出: 它可以很好地递增,但是当它被打印时,我可以看到print + i

  • links 目录 上一节: main.main之前的准备 下一节: 调度器相关数据结构

  • 问题内容: 今天,我一直在与Goroutines,Channels和WaitGroup一起玩耍,在阅读了一段时间后,我终于开始理解这个概念。 我的问题是我不确定如何像这样工作时如何处理错误,主要是因为我使用了WaitGroup。使用WaitGroup时,我首先添加将要执行的goroutine的数量,但是如果其中之一发生错误怎么办? 游乐场:https : //play.golang.org/p/Z