Если я правильно понял, вам нужно предотвратить одновременное выполнение какой-либо части каждой функции и других функций.Следующий код делает это: 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
.Надеюсь, что все проясняет.