На этой неделе мы проделали большую работу. Если вы честно прочитали весь цикл постов о Cloud Haskell, во всем разобрались и прорешали домашку, то можете с чистой совестью пойти в ближайший магазин и купить себе какую-нибудь вкусняшку. Если ничего не поняли, не расстраивайтесь. Спокойно разберитесь в непонятных вопросах и вернитесь к Cloud Haskell через пару-тройку недель. Не пытайтесь разобраться во всем наскоком, в мире Haskell это не работает! В заключение мне хотелось бы поделиться кое-какими своими мыслями, а также привести ссылки на дополнительные материалы по теме.
На данный момент мы уже посмотрели на Cloud Haskell в действии и выяснили, в чем заключаются отличия Cloud Haskell от Erlang. Сегодня же мы посмотрим на основные функции, предоставляемые Cloud Haskell. В том числе, на функции для работы с типизированными каналами, а также функции receiveTimeout, register, whereis, getProcessInfo, и другие. Про распределенщину пока не будет, потому что этот вопрос я и сам еще не до конца осилил :)
Итак, у вас было целых два дня на то, чтобы подготовиться к подаче материала про Cloud Haskell, а также составить общее впечатление об отличиях Cloud Haskell от Erlang. Сегодня же мы наконец-то увидим пусть и простую, но саму что ни на есть настоящую программу, использующую сабж. Возможно, кто-то из читателей предпочел бы сначала ознакомиться с детальным описанием API, но я лично всегда больше любил учиться на примерах, так что API отложим до завтра.
Cloud Haskell — это фреймворк / DSL для разработки конкарент распределенных отказоустойчивых приложений без разделяемого состояния. Типа Erlang, только лучше. Как минимум, за счет строгой статической типизации, компиляции в нативный код и более приятного синтаксиса. Кроме того, как будет показано ниже, Cloud Haskell лишен некоторых родовых травм Erlang’а и в некоторых аспектах более гибок.
Как я уже когда-то писал, потоки в Haskell сделаны как можно более легковесными для минимизации накладных расходов и чтобы поверх них можно было сотворить все что угодно. Прекрасным примером всего что угодно является Cloud Haskell. Это попытка принести в мир Haskell модель акторов а-ля Erlang. И, как оказалось, попытка эта на редкость удачная. Не как Akka.
Продолжаем вспоминать Windows API. До сих пор мы писали грустные и унылые однопоточные программки из серии «вызови правильную процедуру с нужными аргументами и посмотри на ее код возврата». Сегодня же мы наконец-то напишем хоть и простенькую, но все же самую что ни на есть многопоточную программу, с теми самыми тредами и мьютексами, которые все постоянно ругают.
Взаимодействие процессов в Erlang происходит путем обмена сообщений. И хотя сообщения в Erlang дешевы, они не бесплатны. Бездумная посылка сообщений неправо и налево может привести не только к существенному замедлению работы всего приложения, но и к его аварийному завершению.
Программная транзакционная память (software transactional memory, STM) — это механизм взаимодействия между потоками, имеющий ряд существенных преимуществ перед традиционным подходом с использованием блокировок. Благодаря этой заметке вы узнаете, как работать с STM в Haskell.
Как вы уже могли догадаться, я снова взялся за изучение Haskell. Очевидно, этот язык нельзя учить наскоком. Я решил запастись терпением и вникать во все медленно, но верно. Например, недавно я разбирался с многопоточностью.
Многие программы на Erlang прекрасно распараллеливаются. Если некая задача разбивается на независимые части, мы можем просто создать для каждой части отдельный процесс. Однако процессы в Erlang хоть и дешевые, но не бесплатные. Бездумно наплодив кучу процессов, можно с легкостью уронить все приложение. Давайте попробуем решить эту проблему, создав пул процессов фиксированного размера. Задания будут раздаваться этим процессам при помощи gen_server’а, хранящего очередь задач.