Конкурентное удвоение числа с использованием только каналов

Канал с одним токеном сериализует изменение числа, а закрытие отдельного канала останавливает работников. При начальном значении 1 итог — 1024.

Короткий ответ

Что ответить на собеседовании

Канал с одним токеном сериализует изменение числа, а закрытие отдельного канала останавливает работников. При начальном значении 1 итог — 1024.

Подробный разбор

Ответ с пояснениями

Условие

Имеется глобальная переменная (целочисленная) и десять горутин, каждая из которых:

  • Умножает эту переменную на 2.
  • Останавливается, когда значение достигает или превышает 1000. Главная горутина обязана прервать работу всех остальных горутин и вывести окончательный результат.

Требования:

  • Запрещено применять пакеты sync (мьютексы, WaitGroup) и sync/atomic.
  • Весь механизм синхронизации и передачи данных должен быть построен исключительно на каналах.

Ответ

Канал с одним токеном сериализует изменение числа, а закрытие отдельного канала останавливает работников. При начальном значении 1 итог — 1024.

Начальное значение в условии не задано: выберем 1. Для нуля или отрицательного числа удвоение не достигнет порога, поэтому такие начальные значения требуют отдельной проверки.

package main

import "fmt"

var value = 1

func main() {
    token := make(chan struct{}, 1)
    stop := make(chan struct{})
    finished := make(chan struct{}, 10)
    result := make(chan int, 1)
    token <- struct{}{}
    for i := 0; i < 10; i++ {
        go func() {
            defer func() { finished <- struct{}{} }()
            for {
                select {
                case <-stop:
                    return
                case <-token:
                    if value < 1000 { value *= 2 }
                    if value >= 1000 {
                        result <- value
                        return
                    }
                    token <- struct{}{}
                }
            }
        }()
    }
    final := <-result
    close(stop)
    for i := 0; i < 10; i++ { <-finished }
    fmt.Println(final)
}

Достигший порога работник не возвращает токен, поэтому никто не удваивает число дальше. main закрывает stop и ждёт подтверждения завершения всех десяти горутин. Все обращения к общей переменной защищены передачей единственного токена.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее