@Whuthering

Как реализовать распараллеливание в функциональной парадигме без общего состояния?

Вопрос про иммутабельность. Зачем оно нужно, в чем плюсы такого подхода и откуда у него ноги растут — тут всё понятно.
А теперь представим, что мы ведем речь не про F#, где есть mutable, а про какой-нибудь «чисто функциональный» язык, где мутабельных переменных нет вообще. И нам нужно каким-то образом хранить текущеее состояние.
Например, простая задача: мы реагируем на какое-нибудь событие, например, по сети получаем откуда-то пакеты двух типов, и нам нужно посчитать за какое-то время, сколько пришло пакетов первого типа и сколько пришло пакетов второго типа.
Как в такую модель вписывается concurrency/parallelism? Например, мы хотим разгребать полученные пакеты не на одном, а на всех процессорах машины, но при этом счетчик у нас один общий на всех, и мы в ответ на каждый пакет должны посылать в ответ текущее значение счетчика.
В классчическом процедурном или ООП-подходе все просто: есть какая-то глобальная структура или переменная, и потоки ее изменяют, или получая мьютекс, или через lock-free-операции.
Вопрос, как реализовать такое в ФП. Для одного потока, допустим, мы можем сделать функцию, которая проверяет, не пришло ли сообщение от диспетчера, инкрементирует счетчик, шлет ответ, и вызывает саму себя с новым значением счетчика.
Но если у нас несколько потоков или процессов (чтобы задействовать все ядра), то как при отсутствии общего состояния между ними будет шарится текущее значение? Или как можно реализовать решение подобной задачи без оного?
  • Вопрос задан
  • 150 просмотров
Пригласить эксперта
Ответы на вопрос 2
@potan
Функция, которая проверяет наличие сообщения уже не чистая - наличие сообщения уже состояние.
В чистых языках с состоянием работают с помощью монад. Для асинхронных операция есть монада Future (популярная и в распространенных языках). Монада является так же аппликативным функтором, для Future это позволяет выполнять две задачи параллельно и синхронизироваться по их завершению.
Ответ написан
angrySCV
@angrySCV
machine learning, programming, startuping
ну тут целый курс надо читать как правильно делать паралелизацию (по данным или по фукциям).
сейчас речь идет про паралелизацию по данным (есть разные данные о пакетах которые нужно параллельно обработать)
для этого вам нужно в начале уметь правильно разделять данные на параллельно обрабатываемые куски
и функцию агрегации параллельно обработанных данных.
В вашем случае в конце должна быть еще одна функция которая складывает все промежуточные результаты в один итоговый результат.
Само собой ОДИН пакет ты не можешь паралельно считать. Но описанная схема (с разделением и агрегацией) корректно работает и для одного элемента.
П. С.
если что-то параллельно записывать и читать из одного и тогоже места - то в зависимости от реализации алгоритма у тебя будет -> если есть блокировки - то будут дедлоки, если блокировок нет то будут некорректные результаты в ответе (рейскондишен), так что то что ты описал в "классическом стиле", изначально не будет работать корректно.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы