У меня есть приложение, в котором я создаю несколько программ для одновременного выполнения определенной задачи. Все рабочие программы ожидают наступления условия / события, и как только событие инициируется, они начинают свое выполнение. После создания всех подпрограмм главный поток должен знать, что перед отправкой широковещательного сигнала все подпрограммы действительно находятся в состоянии ожидания.
Я знаю, что это можно сделать с помощью каналов (что рекомендуется), но я также обнаружил, чтопакет синхронизации go интересный. Просто пытаюсь понять, как добиться той же функциональности, используя пакет синхронизации вместо каналов
package main
import (
"fmt"
"sync"
"time"
)
var counter int
func worker(wg *sync.WaitGroup, cond *sync.Cond, id int) {
fmt.Println("Starting Goroutine ID:", id)
// Get a lock and wait
cond.L.Lock()
defer cond.L.Unlock()
fmt.Println("Goroutine with ID: ", id, "obtained a lock")
// Do some processing with the shared resource and wait
counter++
wg.Done()
cond.Wait()
fmt.Println("Goroutine ID:", id, "signalled. Continuing...")
}
func main() {
var wg sync.WaitGroup
cond := sync.NewCond(&sync.Mutex{})
counter = 0
for i := 0; i < 5; i++ {
wg.Add(1)
go worker(&wg, cond, i)
}
wg.Wait() // Wait()'ing only until the counter is incremented
// How to make sure that all goroutines you created are indeed wait()'ing ?????
cond.Broadcast()
time.Sleep(2 * time.Second)
cond.Broadcast()
fmt.Println("Final value of the counter is", counter)
}
Если я не использую приведенные ниже операторы в последних 3 строках (кроме fmt.Println)
time.Sleep(2 * time.Second)
cond.Broadcast()
Я получаю следующий вывод ..
Starting Goroutine ID: 4
Goroutine with ID: 4 obtained a lock
Starting Goroutine ID: 3
Goroutine with ID: 3 obtained a lock
Starting Goroutine ID: 1
Goroutine with ID: 1 obtained a lock
Starting Goroutine ID: 0
Goroutine with ID: 0 obtained a lock
Starting Goroutine ID: 2
Goroutine with ID: 2 obtained a lock
Final value of the counter is 5
Goroutine ID: 3 signalled. Continuing...
В идеале каждая goroutine должна иметь возможность печатать
Goroutine ID: 3 signalled. Continuing...
с соответствующим идентификатором goroutine. Мы не можем напечатать это, потому что не все goroutines сигнализируются, поскольку некоторые из них даже не находятся в состоянии ожидания. Вот почему я добавил время. Сон, который не является практическим решением.
Мой вопрос ... Как я могу знать, что все goroutines фактически ожидают при условии cond.Wait () .. Каналырешение, но я хочу знать, как я мог бы сделать это с помощью пакета синхронизации Go?