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

sync.Cond.Signal

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

Синтаксис

c.Signal()

Пример с одной ожидающей горутиной

Рассмотрим базовый пример, где одна горутина ожидает сигнала, а другая отправляет его:

package main import ( "fmt" "sync" "time" ) func main() { var mu sync.Mutex cond := sync.NewCond(&mu) go func() { mu.Lock() defer mu.Unlock() fmt.Println("Горутина ожидает сигнала") cond.Wait() fmt.Println("Горутина получила сигнал") }() time.Sleep(100 * time.Millisecond) mu.Lock() fmt.Println("Отправляем сигнал") cond.Signal() mu.Unlock() time.Sleep(100 * time.Millisecond) }

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

"Горутина ожидает сигнала" "Отправляем сигнал" "Горутина получила сигнал"

Пример с несколькими ожидающими горутинами

Покажем, что метод Signal пробуждает только одну горутину из нескольких ожидающих:

package main import ( "fmt" "sync" "time" ) func main() { var mu sync.Mutex cond := sync.NewCond(&mu) var wg sync.WaitGroup for i := 1; i <= 3; i++ { wg.Add(1) go func(id int) { defer wg.Done() mu.Lock() defer mu.Unlock() fmt.Printf("Горутина %d ожидает\n", id) cond.Wait() fmt.Printf("Горутина %d проснулась\n", id) }(i) } time.Sleep(100 * time.Millisecond) mu.Lock() fmt.Println("Отправляем один сигнал") cond.Signal() mu.Unlock() time.Sleep(100 * time.Millisecond) mu.Lock() fmt.Println("Отправляем второй сигнал") cond.Signal() mu.Unlock() wg.Wait() }

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

"Горутина 3 ожидает" "Горутина 1 ожидает" "Горутина 2 ожидает" "Отправляем один сигнал" "Горутина 3 проснулась" "Отправляем второй сигнал" "Горутина 1 проснулась"

Пример с проверкой условия

Покажем использование метода Signal в связке с проверкой условия в цикле:

package main import ( "fmt" "sync" "time" ) func main() { var mu sync.Mutex cond := sync.NewCond(&mu) ready := false go func() { mu.Lock() defer mu.Unlock() for !ready { fmt.Println("Ожидаем готовности") cond.Wait() } fmt.Println("Условие выполнено!") }() time.Sleep(100 * time.Millisecond) mu.Lock() fmt.Println("Меняем состояние") ready = true cond.Signal() mu.Unlock() time.Sleep(100 * time.Millisecond) }

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

"Ожидаем готовности" "Меняем состояние" "Условие выполнено!"

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

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