РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
853 of 1593 menu

Метод sync.Cond.Broadcast

Метод sync.Cond.Broadcast пробуждает все горутины, которые ожидают на данном условном объекте. В отличие от метода Signal, который пробуждает только одну горутину, Broadcast пробуждает все ожидающие горутины одновременно. Этот метод используется в ситуациях, когда изменение состояния затрагивает всех ожидающих, и все они должны продолжить выполнение.

Синтаксис

c.Broadcast()

Метод не принимает параметров и не возвращает значений. Он вызывается на экземпляре sync.Cond после изменения общего состояния, которое ожидают горутины.

Пример

Давайте рассмотрим базовый пример использования Broadcast для пробуждения всех ожидающих горутин:

package main import ( "fmt" "sync" "time" ) func main() { var mu sync.Mutex cond := sync.NewCond(&mu) var ready bool // Запускаем три горутины, которые ожидают сигнала for i := 1; i <= 3; i++ { go func(id int) { mu.Lock() for !ready { cond.Wait() } fmt.Printf("Goroutine %d: started\n", id) mu.Unlock() }(i) } // Даем горутинам время начать ожидание time.Sleep(100 * time.Millisecond) // Меняем состояние и пробуждаем все горутины mu.Lock() ready = true cond.Broadcast() mu.Unlock() // Даем время на вывод результатов time.Sleep(200 * time.Millisecond) }

Результат выполнения кода:

"Goroutine 3: started" "Goroutine 1: started" "Goroutine 2: started"

В этом примере все три горутины ожидают изменения переменной ready. После вызова Broadcast все они пробуждаются и продолжают выполнение. Порядок вывода может отличаться.

Пример

Давайте сравним поведение Broadcast и Signal на практическом примере:

package main import ( "fmt" "sync" "time" ) func main() { var mu sync.Mutex cond := sync.NewCond(&mu) var dataReady bool var wg sync.WaitGroup // Запускаем 5 горутин, ожидающих данные for i := 1; i <= 5; i++ { wg.Add(1) go func(id int) { defer wg.Done() mu.Lock() for !dataReady { cond.Wait() } fmt.Printf("Worker %d: processing data\n", id) mu.Unlock() }(i) } time.Sleep(100 * time.Millisecond) // Подготавливаем данные и пробуждаем всех mu.Lock() dataReady = true fmt.Println("Main: data ready, broadcasting...") cond.Broadcast() mu.Unlock() wg.Wait() }

Результат выполнения кода:

"Main: data ready, broadcasting..." "Worker 5: processing data" "Worker 2: processing data" "Worker 1: processing data" "Worker 3: processing data" "Worker 4: processing data"

В этом примере все пять воркеров ожидают готовности данных. Использование Broadcast позволяет запустить их всех одновременно. Если бы мы использовали Signal, то пробудилась бы только одна горутина.

Пример

Давайте рассмотрим пример с циклическим пробуждением всех горутин на каждом этапе:

package main import ( "fmt" "sync" "time" ) func main() { var mu sync.Mutex cond := sync.NewCond(&mu) stage := 0 var wg sync.WaitGroup // Запускаем горутины, ожидающие этапов for i := 1; i <= 3; i++ { wg.Add(1) go func(id int) { defer wg.Done() for stage < 3 { mu.Lock() for stage == 0 { cond.Wait() } fmt.Printf("Worker %d: stage %d completed\n", id, stage) mu.Unlock() } fmt.Printf("Worker %d: all stages done\n", id) }(i) } // Последовательно проходим этапы for s := 1; s <= 3; s++ { time.Sleep(200 * time.Millisecond) mu.Lock() stage = s fmt.Printf("Main: stage %d ready\n", s) cond.Broadcast() mu.Unlock() } wg.Wait() }

Результат выполнения кода:

"Main: stage 1 ready" "Worker 3: stage 1 completed" "Worker 1: stage 1 completed" "Worker 2: stage 1 completed" "Main: stage 2 ready" "Worker 2: stage 2 completed" "Worker 1: stage 2 completed" "Worker 3: stage 2 completed" "Main: stage 3 ready" "Worker 3: stage 3 completed" "Worker 2: stage 3 completed" "Worker 1: stage 3 completed" "Worker 1: all stages done" "Worker 2: all stages done" "Worker 3: all stages done"

В этом примере Broadcast используется на каждом этапе для пробуждения всех горутин, которые затем обрабатывают текущий этап и снова переходят в ожидание.

Смотрите также

  • метод sync.Cond.Signal,
    который пробуждает одну ожидающую горутину
  • метод sync.Cond.Wait,
    который переводит горутину в режим ожидания
  • структуру sync.Cond,
    которая представляет условную переменную
  • метод sync.NewCond,
    который создает новый условный объект
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить