Я вообще не использовал многопоточность в Clojure, поэтому не знаю, с чего начать.
У меня есть doseq
, тело которого может работать параллельно. Я бы хотел, чтобы всегда было 3 потока (оставляя 1 ядро бесплатно), которые оценивают тело параллельно, пока диапазон не исчерпан. Нет никакого общего состояния, ничего сложного - эквивалент многопроцессорности Python был бы прекрасен.
Так что-то вроде:
(dopar 3 [i (range 100)]
; repeated 100 times in 3 parallel threads...
...)
С чего начать? Есть ли команда для этого? Стандартный пакет? Хорошая ссылка?
До сих пор я нашел pmap
и мог бы использовать это (как мне ограничить 3 за раз? похоже, что он использует 32 за раз - нет, источник говорит 2 + количество процессоров), но похоже, что это базовый примитив, который уже должен существовать где-то.
пояснение: я действительно хотел бы контролировать количество потоков. У меня есть процессы, которые долгое время работают и используют достаточное количество памяти, поэтому создание большого количества и надеяться, что все будет хорошо, - это не хороший подход (пример, который использует значительный фрагмент доступный mem).
update: начиная писать макрос, который делает это, и мне нужен семафор (или мьютекс, или атом, который я могу ждать). Существуют ли семафоры в Clojure? Или я должен использовать ThreadPoolExecutor? Кажется странным, что приходится так много тянуть с Java - я думал, что параллельное программирование в Clojure должно быть легким... Может быть, я думаю об этом совершенно неправильно? Хммм. Агенты?