go - 并发协程的互斥

标签 go concurrency 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
}

我希望,当两个代码之间的代码(两个星号之间的代码)正在执行时,控制流不能转到其他 goroutines。例如,当例程 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()
}

更新:让我在这里解释一下这三个互斥量:互斥量是documentation says。 :“互斥锁。”这意味着当您在互斥量上调用 Lock 时,如果其他人锁定了同一个互斥量,您的代码就会在那里等待。在您调用 Unlock 后,被阻止的代码将立即恢复。

在这里,我通过在函数开头锁定互斥锁并在函数结束时解锁它,将每个函数放入其自己的互斥锁中。通过这种简单的机制,您可以避免在运行这些函数的同时运行您想要的任何代码部分。例如,当 Routine1 正在运行时,您希望在任何地方都有不应该运行的代码,只需在该代码的开头锁定 mutex1 并在结尾解锁。这就是我在 Routine2Routine3 的适当行中所做的。希望澄清事情。

关于go - 并发协程的互斥,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8315970/

相关文章:

go - 同时多次下载同一文件

multithreading - 如果 goroutines 涉及用户空间线程,阻塞操作是否会导致整个线程的上下文切换?

go - 如何在 Visual Studio Code 中使用 Cgo 调试 Go

function - 改变值(value)

go - Golang如何获取当前源文件的最新编译时间和日期?

multithreading - Erlang中Actor的基本解释

azure - 在 Azure API 管理中设置并发限制

go - 在golang ssh session 关闭中将EOF作为错误

go - 如何编写更好的双 channel 选择

go - 在同一个 goroutines 中创建的 goroutines 是否总是按顺序执行?