小编典典

并发Goroutine互斥

go

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

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
}

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

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


阅读 306

收藏
2020-07-02

共1个答案

小编典典

如果我正确理解了它,那么您想要的是防止同时执行每个功能的某些部分和其他功能。下面的代码执行此操作: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。希望能澄清一些事情。

2020-07-02