Пора заканчивать заниматься ерундой и писать всякую фигню o Perl - блог закрыт. Сажусь за написание двух книг.
Первая книга будет называется "Событийное программирование на Perl для домохозяек или как успеть приготовить тысячу блюд к приходу гостей".
Вторая - "Распределенное программирование на Perl для домохозяек".
Эта книга предназначена для тех, кто любому кухонному комбайну предпочитает набор хороших кухонных ножей.
Логичней было начать с первой, но вторая сейчас интересней, поэтому есть большая вероятность, что первая будет лишь брошюркой.
Здесь будет опубликованы анонсы. До встречи.
среда, 3 февраля 2010 г.
понедельник, 4 января 2010 г.
Если бы в Perl не было бы списков :-)
Новогодние каникулы продолжаются...
Иногда в праздничном веселье, как нечто далекое, мелькают мысли: кто я, что я делал, perl какой-то...
Создание списка
Печать списка
map
Иногда в праздничном веселье, как нечто далекое, мелькают мысли: кто я, что я делал, perl какой-то...
Создание списка
sub list($;$) {
my ($h, $t) = @_;
return sub {
return $h, $t;
}
}
my $x1 = list(1);
my $x2 = list(2, $x1);
my $x3 = list(3, $x2);
Печать списка
sub print_list($);
sub print_list($) {
my ($list) = @_;
my ($h, $t) = $list->();
print_list($t) if $t;
print "$h ";
}
print_list $x3;
print "\n";
map
sub _Map {
my ($sub, $list) = @_;
my ($h, $t) = $list->();
my $r = $t ? _Map($sub, $t) : undef;
list($sub->($h), $r);
}
sub Map(&;$) { &_Map }
print_list Map { $_[0]**$_[0] } $x3;
print "\n";
понедельник, 28 декабря 2009 г.
Open, каналы и ожидание завершения потомка
Трудно искать черную кошку в темной комнате, особенно, если ее там нет.
Но как оказалось, еще трудней не замечать черную кошку, сидящую на видном месте в ярко освещенной комнате!
Так вот и я потратил приличную часть времени, заметив, что в коде, упрошенном до нижеследующего, родительский процесс ожидает завершения потомка:
Впредь, если для дочернего процесса может истечь тайм-аут, буду использовать вызов pipe:
Или буду использовать socketpair.
С другой стороны, вред от первого варианта на практике всегда отсутствует, наверно поэтому и не замечал этого явления на протяжении многих лет.
Но как оказалось, еще трудней не замечать черную кошку, сидящую на видном месте в ярко освещенной комнате!
Так вот и я потратил приличную часть времени, заметив, что в коде, упрошенном до нижеследующего, родительский процесс ожидает завершения потомка:
my $child_sub = sub { sleep };
my $child_pid = open my $fh, "-|";
defined $child_pid or die "Can't fork: $!";
if ($child_pid) {
# Родитель.
} else {
# Ребенок.
$child_sub->();
exit;
}
Впредь, если для дочернего процесса может истечь тайм-аут, буду использовать вызов pipe:
my $child_sub = sub { sleep };
pipe my $from_child_fh, my $to_parent_fh or die "pipe: $!";
my $child_pid = fork;
defined $child_pid or die "Can't fork: $!";
if ($child_pid) {
# Родитель.
close $to_parent_fh;
} else {
# Ребенок.
close $from_child_fh;
$child_sub->();
exit;
}
Или буду использовать socketpair.
С другой стороны, вред от первого варианта на практике всегда отсутствует, наверно поэтому и не замечал этого явления на протяжении многих лет.
понедельник, 21 декабря 2009 г.
Настоящие джедаи не используют threads
Поскольку термин потоки (threads) очень многогранный, сразу скажу, что под этим термином в этой заметке подразумевается лишь пользовательские потоки операционной системы и Perl потоки, и никаким образом не ядерные потоки, имеющие другую суть.
Еще на заре истории старые мастера предупреждали, что потоки, разделяемые данные, блокировки и семафоры - это не хорошо, излишне и путано. Достаточно процессов и мультиплексирования. Но не послушали их, и были созданы пользовательские потоки, внеся в этот мир сумятицу и сложность. Да и как создали? Эх...
В Linux пошли по самому легкому пути: по сути потоки являются немного облегченными процессами. Горячие головы пытались исправить это, но увидели мытарства разработчиков Solaris остудили свой пыл. И только в Windows-NT один из старых мастеров-ренегатов создал нормальные потоки. Но это была медвежья услуга - мир захотел потоков еще больше.
Даже в лагере BSD начались волнения. Потоки во FreeBSD были, но о них ядро ничего не знало со всеми вытекающими последствиями. Поэтому в основном использовали реализацию Linux потоков. Но лучшая реализация Windows потоков не давала покоя и разработчики решили, что смогут сделать то, что не удалось сделать в Solaris. Так появилась FreeBSD 5 с KSE. Потом выпустили FreeBSD 6, затем 7 и вот недавно - 8, в которой от KSE не осталось ни следа, а потоки во FreeBSD стали иметь модель как у Windows и Solaris: 1 к 1.
Но не все так мрачно. Еще по времена FreeBSD 4, один из джедаев, помня советы старых мастеров, сделал форк FreeBSD и назвал его DragonFlyBSD. Одной из целей этого проекта стала очистка от блокировок и всего, что мешает масштабированию системы. Вместо блокировок - сообщения.
И в мире повыше, чем системное программирование, есть островки надежды. Например Erlang, с концепцией легковесных процессов, общающихся посредством сообщений. Также интересен Mozart-OZ. Да и функциональные языки хорошо распараллеливаются. Эти подходы позволяют скрыть от простого программиста "сложность" мультиплексирования и межпроцессорного взаимодействия не внося при этом недостатки, свойственные потокам. А настоящие джедаи понимают, что эта сложность лишь иллюзия.
Что касается Perl, то он у меня до сих пор собран без поддержки потоков.
Ой, как в этой заметки оказался Perl? Просто эта заметка является исповедью: мне пришлось написать многопоточное приложение на Perl.
Но перед советом джедаев у меня есть два оправдания: мультиплексирующая и многопроцессная версии этого приложения!
В многопроцессной версии взаимодействие между процессами реализовано посредством сообщений. Такая архитектура позволила многопроцессной версии быть более производительной, чем многопоточная, использующей разделяемые переменные и блокировки. Многопроцессная версия также оказалась чуть проще - не приходилось заботиться о минимизации времени блокировок. Не было нужды также держать перед глазами лист бумаги с порядком блокировок в каждом из потоков, чтобы ненароком не создать патовую ситуацию.
Все таки был прав батюшка из фильма "Королева бензоколонки", сказав: "к полумерам не привык", либо процессы, либо мультиплексирование (ситуацию с Windows не рассматриваем).
P.S.
Перечитал - сплошной вихрь эмоций, а не заметка.
P.P.S.
Радует то, что разработчика Perl уже давно трезво смотрят на потоки. Для эмуляции системного вызова fork под Windows и для использования mod_perl2 с Apache2 в многопоточном режиме они реализовали многопоточность на основе копий интерпретатора Perl, а предыдущей модели Perl потоков забыли как о страшном сне.
Разработчики же других динамических языков все еще находятся в эйфории от потоков, благо их языки намного проще. Например, вчера случайно попал на совещание питоноводов, на котором обсуждались вопрос частого падения их проекта при высокой нагрузке, а также вопрос, почему часто вместо ожидаемых данных возвращается другая информация, как будто от другого запроса. Услышав это, зная как реализованы потоки в питоне, порекомендовал использовать Apache2 в многопроцессном режиме работы. Система стала работать стабильно и корректно.
Еще на заре истории старые мастера предупреждали, что потоки, разделяемые данные, блокировки и семафоры - это не хорошо, излишне и путано. Достаточно процессов и мультиплексирования. Но не послушали их, и были созданы пользовательские потоки, внеся в этот мир сумятицу и сложность. Да и как создали? Эх...
В Linux пошли по самому легкому пути: по сути потоки являются немного облегченными процессами. Горячие головы пытались исправить это, но увидели мытарства разработчиков Solaris остудили свой пыл. И только в Windows-NT один из старых мастеров-ренегатов создал нормальные потоки. Но это была медвежья услуга - мир захотел потоков еще больше.
Даже в лагере BSD начались волнения. Потоки во FreeBSD были, но о них ядро ничего не знало со всеми вытекающими последствиями. Поэтому в основном использовали реализацию Linux потоков. Но лучшая реализация Windows потоков не давала покоя и разработчики решили, что смогут сделать то, что не удалось сделать в Solaris. Так появилась FreeBSD 5 с KSE. Потом выпустили FreeBSD 6, затем 7 и вот недавно - 8, в которой от KSE не осталось ни следа, а потоки во FreeBSD стали иметь модель как у Windows и Solaris: 1 к 1.
Но не все так мрачно. Еще по времена FreeBSD 4, один из джедаев, помня советы старых мастеров, сделал форк FreeBSD и назвал его DragonFlyBSD. Одной из целей этого проекта стала очистка от блокировок и всего, что мешает масштабированию системы. Вместо блокировок - сообщения.
И в мире повыше, чем системное программирование, есть островки надежды. Например Erlang, с концепцией легковесных процессов, общающихся посредством сообщений. Также интересен Mozart-OZ. Да и функциональные языки хорошо распараллеливаются. Эти подходы позволяют скрыть от простого программиста "сложность" мультиплексирования и межпроцессорного взаимодействия не внося при этом недостатки, свойственные потокам. А настоящие джедаи понимают, что эта сложность лишь иллюзия.
Что касается Perl, то он у меня до сих пор собран без поддержки потоков.
Ой, как в этой заметки оказался Perl? Просто эта заметка является исповедью: мне пришлось написать многопоточное приложение на Perl.
Но перед советом джедаев у меня есть два оправдания: мультиплексирующая и многопроцессная версии этого приложения!
В многопроцессной версии взаимодействие между процессами реализовано посредством сообщений. Такая архитектура позволила многопроцессной версии быть более производительной, чем многопоточная, использующей разделяемые переменные и блокировки. Многопроцессная версия также оказалась чуть проще - не приходилось заботиться о минимизации времени блокировок. Не было нужды также держать перед глазами лист бумаги с порядком блокировок в каждом из потоков, чтобы ненароком не создать патовую ситуацию.
Все таки был прав батюшка из фильма "Королева бензоколонки", сказав: "к полумерам не привык", либо процессы, либо мультиплексирование (ситуацию с Windows не рассматриваем).
P.S.
Перечитал - сплошной вихрь эмоций, а не заметка.
P.P.S.
Радует то, что разработчика Perl уже давно трезво смотрят на потоки. Для эмуляции системного вызова fork под Windows и для использования mod_perl2 с Apache2 в многопоточном режиме они реализовали многопоточность на основе копий интерпретатора Perl, а предыдущей модели Perl потоков забыли как о страшном сне.
Разработчики же других динамических языков все еще находятся в эйфории от потоков, благо их языки намного проще. Например, вчера случайно попал на совещание питоноводов, на котором обсуждались вопрос частого падения их проекта при высокой нагрузке, а также вопрос, почему часто вместо ожидаемых данных возвращается другая информация, как будто от другого запроса. Услышав это, зная как реализованы потоки в питоне, порекомендовал использовать Apache2 в многопроцессном режиме работы. Система стала работать стабильно и корректно.
понедельник, 14 декабря 2009 г.
Почему я не использую ORM
Для Perl на CPAN существует большое количество различным ORM, да и очень часто на конференциях делают доклады о них.
Поэтому меня время от времени возникала мысль написать cтатью "Почему я не использую ORM".
Но потом я увидел одну фразу, и смыл в данной статье отпал, так как в этой одной простой фразе содержался исчерпывающий ответ.
Вот эта фраза, сказанная http://plumqqz.livejournal.com:
"Высокоуровневый декларативный язык (SQL) в случае ORM заменяется низкоуровневым процедурным..."
От себя вкратце добавлю, что не использую в основном потому что:
1. Движки баз слишком разные. И от базы зависит не только как выбрать информацию с таблиц, но сама структура таблиц и индексов.
2. ORM - это лишний промежуточный слой...
Но, я не всегда пишу чистый SQL. Иногда генерирую его с более высокоуровневого MetaSQL, который учитывает специфику конкретного проекта. Да и MetaSQL иногда бывает частью некого декларативного описания более высокого уровня и генерируется на его основе, совместно с генерацией части Perl кода.
Поэтому меня время от времени возникала мысль написать cтатью "Почему я не использую ORM".
Но потом я увидел одну фразу, и смыл в данной статье отпал, так как в этой одной простой фразе содержался исчерпывающий ответ.
Вот эта фраза, сказанная http://plumqqz.livejournal.com:
"Высокоуровневый декларативный язык (SQL) в случае ORM заменяется низкоуровневым процедурным..."
От себя вкратце добавлю, что не использую в основном потому что:
1. Движки баз слишком разные. И от базы зависит не только как выбрать информацию с таблиц, но сама структура таблиц и индексов.
2. ORM - это лишний промежуточный слой...
Но, я не всегда пишу чистый SQL. Иногда генерирую его с более высокоуровневого MetaSQL, который учитывает специфику конкретного проекта. Да и MetaSQL иногда бывает частью некого декларативного описания более высокого уровня и генерируется на его основе, совместно с генерацией части Perl кода.
понедельник, 7 декабря 2009 г.
Обновил модуль BGS
Обновил модуль BGS - Background execution of subroutines in child processes.
Вместо open используется pipe - теперь дочерний процесс может печатать на STDOUT.
Также сделал, что bgs_call возвращает PID дочернего процесса. Зачем это сделал - не знаю,
наверно, надо было бы лучше добавить проверку на допустимость возвращаемого значения блока bgs_call.
Вместо open используется pipe - теперь дочерний процесс может печатать на STDOUT.
Также сделал, что bgs_call возвращает PID дочернего процесса. Зачем это сделал - не знаю,
наверно, надо было бы лучше добавить проверку на допустимость возвращаемого значения блока bgs_call.
понедельник, 30 ноября 2009 г.
do, eval и return
Написал
держа в голове
А не надо было в варианте с do использовать return, так как это выход не из do, а из подпрограммы, содержащей do.
:-)
my (@foo) = do {
...
return ...
};
держа в голове
my (@foo) = eval {
...
return ...
};
А не надо было в варианте с do использовать return, так как это выход не из do, а из подпрограммы, содержащей do.
:-)
Подписаться на:
Сообщения (Atom)