为了账号安全,请及时绑定邮箱和手机立即绑定

并发goroutine的互斥

并发goroutine的互斥

Go
子衿沉夜 2021-05-05 09:21:24
在我的代码中,有三个并发例程。我尝试简要概述一下我的代码,Routine 1 {do something*Send int to Routine 2Send int to Routine 3Print SomethingPrint Something*do something}Routine 2 {do something*Send int to Routine 1Send int to Routine 3Print SomethingPrint Something*do something}Routine 3 {do something*Send int to Routine 1Send int to Routine 2Print SomethingPrint Something*do something}main {routine1routine2routine3}我希望在执行两个代码之间的某些操作(两个星号之间的代码)时,控制流一定不能进入其他goroutine。例如,当例程1正在执行两颗星之间的事件(发送和打印事件)时,例程2和3必须被阻止(执行的平均流量不会从例程1传递到例程2或3)。在完成上一个打印事件后,执行流程可能会传递到例程2或3。有人可以通过指定帮助我的方式,我该如何实现呢?是否可以通过WaitGroup来实现上述规范?任何人都可以通过举一个简单的示例向我展示如何使用WaitGroup来实现上面指定的示例。谢谢。注意:我提供两个发送和两个打印选项,实际上有很多发送和打印功能。
查看完整描述

3 回答

?
潇湘沐

TA贡献1816条经验 获得超6个赞

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


查看完整回答
反对 回复 2021-05-10
?
一只甜甜圈

TA贡献1836条经验 获得超5个赞

另一种方法是拥有一个控制通道,在任何时候只允许执行一个goroutine,并且每当它们完成其原子操作时,每个例程就会发回“ control lock”:


package main

import "fmt"

import "time"


func routine(id int, control chan struct{}){

    for {

        // Get the control

        <-control

        fmt.Printf("routine %d got control\n", id)

        fmt.Printf("A lot of things happen here...")

        time.Sleep(1)

        fmt.Printf("... but only in routine %d !\n", id)

        fmt.Printf("routine %d gives back control\n", id)

        // Sending back the control to whichever other routine catches it

        control<-struct{}{}

    }

}


func main() {

    // Control channel is blocking

    control := make(chan struct{})


    // Start all routines

    go routine(0, control)

    go routine(1, control)

    go routine(2, control)


    // Sending control to whichever catches it first

    control<-struct{}{}

    // Let routines play for some time...

    time.Sleep(10)

    // Getting control back and terminating

    <-control

    close(control)

    fmt.Println("Finished !")

}

打印:


routine 0 got control

A lot of things happen here...... but only in routine 0 !

routine 0 gives back control

routine 1 got control

A lot of things happen here...... but only in routine 1 !

routine 1 gives back control

routine 2 got control

A lot of things happen here...... but only in routine 2 !

routine 2 gives back control

routine 0 got control

A lot of things happen here...... but only in routine 0 !

routine 0 gives back control

routine 1 got control

A lot of things happen here...... but only in routine 1 !

routine 1 gives back control

routine 2 got control

A lot of things happen here...... but only in routine 2 !

routine 2 gives back control

routine 0 got control

A lot of things happen here...... but only in routine 0 !

routine 0 gives back control

routine 1 got control

A lot of things happen here...... but only in routine 1 !

routine 1 gives back control

routine 2 got control

A lot of things happen here...... but only in routine 2 !

routine 2 gives back control

routine 0 got control

A lot of things happen here...... but only in routine 0 !

routine 0 gives back control

routine 1 got control

A lot of things happen here...... but only in routine 1 !

routine 1 gives back control

routine 2 got control

A lot of things happen here...... but only in routine 2 !

routine 2 gives back control

Finished !


查看完整回答
反对 回复 2021-05-10
  • 3 回答
  • 0 关注
  • 192 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信