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。希望能澄清一些事情。
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 !
- 3 回答
- 0 关注
- 209 浏览
添加回答
举报