Открыть меню

Параллелизм в golang на пальцах

Некоторые концепции лучше осознавать при помощи аналогий.

Итак, goroutines (горутины) — подпрограммы, которые запускаются и начинают вести свою жизнь отдельно от вызвавшего их кода.

И вот близкий к жизни пример: компания по доставке пиццы, начинается очередной рабочий день, заходит менеджер, дает наставление в колцентр, не дожидается ответа и заходит в цех — благославляет поваров на работу, так же не ждёт от них ответа и идёт отдыхать. А в это время кипит работа — ребята клепают пиццы раз в секунду, как рабы на галерах:

Результат запуска:

Это был пример, когда два процесса идут параллельно без всякой взаимосвязи (упрощенно, хотя, конечно, на самом деле она есть).

Так вот, когда параллельные процессы логически как-то связаны — их можно соединить каналом связи. И посылать сообщения от одного процесса к другому. При чём, в оба направления.

Небуферизированный канал

Рассмотрим наш цех подробнее. Представим, что он неплохо автоматизирован и там царит тотальное разделение труда. Первый повар раскатывает тесто, второй накладывает начинку, третий кладет в печь и забирает готовую пиццу, четвертый пакует продукцию. Повара — это горутины.

Представим, что они сообщаются напрямую. Вот раскатал парень лепешку, повернулся ко второму и тянет к нему — на держи. Это неплохой пример небуферизированного канала. Пока второй повар не возьмет лепешку у первого, первый так и будет держать её и не станет браться за новую пиццу.  Как только второй соизволит принять — первый продолжит работу. Так и в обратном направлении. Допустим, что второй уже положил начинку и ему нужна новая основа — обращается к первому, а тот её только начал делать. Второй не сможет продолжить работу, пока первый не отдаст основу.

Буферизированный канал

Пример буферизированного канала — тот же цех, только между поварами ещё стоят столы и теперь они не тянут пиццу друг другу напрямую, а кладут на стол в ожидании, что следующий повар возьмет заготовку с неё. Ёмкость канала — количество мест на столе, допустим, равно двум. Представим, что паковщик пошёл пить чай. Теперь третий повар не остановится после первой пиццы, он сделает две, положит их на стол, сделает третью и остановится, потому что складывать уже некуда. Когда паковщик получит по шапке и прибежит на рабочее место, он сможет забирать по одной пицце со стола.

В go можно закрыть канал: приходит менеджер и говорит

— хорош, парни, пакуйте последнюю партию и расходимся.

А для уверенности подходит к столу с готовой пиццей (после третьего повара) и ставит перед ним табличку «больше пиццу не класть». В таком случае паковщик сможет получить последнюю партию в количестве 2-ух штук, но не больше. А третий повар при попытке подкинуть ещё одну штуку на стол получит от менеджера порицание в виде panic)

К слову, закрыть канал можно как со стороны отправителя, так и принимающего.

Обсуждение: 2 комментария
  1. kl09:

    И причем тут параллелизм? Это конкуренция — concurrency.

    Ответить
    1. admin:

      concurrency и переводится как раз, как параллелизм. Откуда взята конкуренция?

      Ответить

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

© 2022 Продвижение сайтов в Санкт-Петербурге · Копирование материалов сайта без разрешения запрещено