LINUX.ORG.RU
ФорумTalks

Почем fork для народа?


0

0

То что форк в Юниксе вещь дорогая, я знал. 
И вот решил сравнить, почем форк на разных Юниксах и платформах.
Вот что получилось:

OС (платформа)     |  Относит. стоимость
-------------------|---------------------
Linux (intel)      |      100
AIX (RS/6000)      |      200
Tru64 (alpha)      |      280
HP-UX (SD16000)    |      320
Solaris9 (Ultra10) |      400
-------------------|----------------------
Windows            |      3350
------------------------------------------


Как измерялось (Юникс):
Всего один fork в цикле (/usr/bin/test)

#! /bin/ksh

integer i=1
integer a=2
integer b=1
while test $i '-lt' 320000; do
#while /usr/bin/test $i '-lt' 1000; do
        i=$i+1
        b=$a*$i
done

Числа 1000 и 300000 подбирались, так чтобы скрипт отрабатывал
за одно и тоже время.
---------------------------------------------------------------------
Винда мне не интересна, но мерялось так:
> cat.exe cpu_test.sh
i=1
a=2
b=1
while test $i '-lt' 1000000; do
#while test.exe $i '-lt' 300; do
        i=$(($i+1))
        b=$(($a*$i))
done

sh.exe cpu_test.sh
----------------------------------------------------------------------
★★★★★
Ответ на: комментарий от fghj

Нет у меня доступных хBSD. 
У кого есть, померяйте, дело нескольких минут.

sdio ★★★★★
() автор топика
Ответ на: комментарий от robot12

В относительных, в зависимости от использование builtin test 
или external /usr/bin/test (fork)

while          test $i '-lt' 1000000 ; do
while /usr/bin/test $i '-lt' 10000   ; do
                             ^^^^^^^^^^^^^^ разница в 100раз по времени

sdio ★★★★★
() автор топика
Ответ на: комментарий от Shaman007

ОК, завтра автоматом по разным компам прогоню, одновременно со сбором инфы о них. И выложу, если получится интересным. Если нет, то выложу инфу о железе для тех компов, на которых гонял тестик.

sdio ★★★★★
() автор топика
Ответ на: комментарий от Shaman007

А началось все со скрипта на ksh, работавшего 43 минуты.
Сейчас он отрабатывает за считаные секунды.

sdio ★★★★★
() автор топика

Sorry, форматирование не то выбрал :-(

> То что форк в Юниксе вещь дорогая, я знал. 

Вас, уважаемый sdio, ввели в заблуждение, fork() в Unix
достаточно дешевый. 

> И вот решил сравнить, почем форк на разных Юниксах и платформах.
> Вот что получилось:

Да не получилось! То есть получилось, но совсем не то. Вы, мил 
человек, меряете не fork(), а fork()+exec(). Почувствуйте разницу.

Сравним издержки на fork() и exec() на простом примере - делаем
с цикле fork/waitpid, а в child процессе делаем или не делаем
exec такой простой штуки, как /bin/true :

$ cat ftest.c
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>

void die(char* msg) { perror(msg); exit(1); }

int main(int ac, char** av)
{
    int n = atoi(av[1]);
    int do_exec = (*av[2] == 'w');
    int i, pid;

    printf("Doing %d iteration, do_exec=%d\n", n, do_exec);

    for (i=0; i<n; i++)
    {
        if ((pid=fork()) == -1)   die("fork");

        if (pid)
        {
            if (waitpid(pid, NULL, 0) == -1)  die("waitpid in parent");
        }
        else
        {
            if (do_exec)
            {
                if (execl("/bin/true", "/bin/true", NULL))  die("execl in child");
            }
            else
            {
                exit(0);
            }
        }
    }
}

$ gcc -O0 ftest.c -o ftest
$ time ./ftest 50000 with_exec
Doing 50000 iteration, do_exec=1

real    1m49.592s
user    0m44.833s
sys     0m46.690s
$ time ./ftest 50000 no_exec
Doing 50000 iteration, do_exec=0

real    0m8.159s
user    0m2.127s
sys     0m4.547s
$

Абсолютные числа значения не имеют однако видим, что расходы на exec
(даже такого простенького экзешника) в 10 раз превосходят расходы на
fork().
Однако результаты ваших экспериментов все равно интересно почитать ;-)

Onanim
()

А мне бы интереснее всего было бы сравнение таких штук:

1. fork() vs. vfork(); vfork() vs. pthread_create() -- как я понимаю, если такое сравнение возможно в принципе, то результаты второго теста должны примерно совпасть. Насколько правомерен код типа if(vfork() == (pid_t)0) exit(0); ?

2. Юниховые [v]fork()+exec() с Оффтопиковым аналогом (как он там называется, не помню).

Кому не лень, спробуйте?

Только, наверное, это отразит истину начиная лишь с двухголовых машин.

Die-Hard ★★★★★
()
Ответ на: комментарий от sdio

> Не спорю, пусть fork+exec, шел-скрипту от этого не легче.

Ну новички-то не будут вникать, они вам поверят, что fork()
действительно страшно дорогой, станут чуть что хвататься за
multithreading даже в тех случаях, где fork'а и сопроцессов
за глаза хватает. Вам это надо? ;-)

А насчет шелл-скриптов... AFAIK любой tutorial по шелл скриптам
предупреждает, что шелл builtins намного быстрее вызова внешних
команд (для этого они, builtins, и есть!). И если вы использовали
вызов внешней программы в цикле(-ах), которые крутятся много раз
то сами понимаете - КССЗБ. А на fork() не стоит пенять :-D

Onanim
()
Ответ на: комментарий от Die-Hard

> А мне бы интереснее всего было бы сравнение таких штук:

> 1. fork() vs. vfork();

А зачем их сравнивать? vfork() имеет смысл только перед немедленным
exec(). Ну допустим даже и будет vfork() немного быстрее fork(),
все равно основные издержки придутся на exec()
Пора уже в 21 веке, при операционках, которые умеют COW закопать этот
vfork и забыть ;-)

> vfork() vs. pthread_create() -- как я понимаю, если такое сравнение

Ну блин, ты же понимаешь - это яблоки и апельсины. Зачем сравнивать?

Однако согласен, что забавно сравнить fork/watpid и pthread_create/pthread_join.

Onanim
()
Ответ на: комментарий от Onanim

Onanim:

> А зачем их сравнивать? vfork() имеет смысл только перед немедленным exec().

Блин, не догоняешь :)... В этом и весь кайф!

> Ну допустим даже и будет vfork() немного быстрее fork(), все равно основные издержки придутся на exec()

Самый толстый оверхэд заключается в том, что после форка надо пройтись по всем страницам и пометить их, как грязные (для грядущего COW'а). vfork() этого не делает. Отсюда вопросы:

1. Насколько этот оверхэд ДЕЙСТВИТЕЛЬНО велик? (fork() vs. vfork())

2. Насколько существенна вся остальная тягомотина с таблицами и кэшами? (vfork() vs. pthread_create())

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

Die-Hard:
> > А зачем их сравнивать? vfork() имеет смысл только перед немедленным exec(). 

> Блин, не догоняешь :)... В этом и весь кайф!

Не догоняю... но если ты настаиваешь - сравним! ;-)
Сравнивать просто fork vs vfork очевидно нельзя, ибо vfork сам
по себе никакого смысла не имеет и употребляться без exec() не может.
Итак сравниваем связки fork+exec vs vfork+exec. Согласен? Поехали!

$ cat vftest.c
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>

void die(char* msg) { perror(msg); exit(1); }

int main(int ac, char** av)
{
    int n = atoi(av[1]);
    int do_vfork = (*av[2] == 'v');
    int i, pid;

    printf("Doing %d iterations with do_vfork=%d \n", n, do_vfork);

    for (i=0; i<n; i++)
    {
        if ( (pid = (do_vfork ? vfork() : fork())) == -1 )  die("[v]fork\n");

        if (pid)
        {
            if (waitpid(pid, NULL, 0) == -1)  die("waitpid in parent");
        }
        else
        {
            execl("/bin/true", "/bin/true", NULL);
            die("execl in child");
        }
    }
}

$ make vftest
cc     vftest.c   -o vftest
$ time ./vftest 50000 fork
Doing 50000 iterations with do_vfork=0

real    1m47.656s
user    0m43.887s
sys     0m47.351s
$ time ./vftest 50000 vfork
Doing 50000 iterations with do_vfork=1

real    1m36.816s
user    0m41.502s
sys     0m41.453s
$

Ну и? В синтетическом тесте мы получили смешную экономию :-)))
В реальной программе, которая делает что-то полезное, а не только
молотит fork/exec эта разница стремительно приблизится вообще к нулю.
BTW прочитай man vfork на Linux, там кое-что и про overhead написано.
Ну а мне достаточно того, что man'ы Solaris, AIX и Linux не
рекомендуют vfork. Я не мазохист ;-)

> 1. Насколько этот оверхэд ДЕЙСТВИТЕЛЬНО велик? (fork() vs. vfork())

Нет никакого оверхеда fork() vs. vfork(). Ну то есть семантика
этой операции сравнения не определена :-))) Только в связке с exec.
Как ты будешь использовать vfork без exec? Ну еще конечно можно
вместо exec сразу _exit. Могу сделать такой тест тоже - только
зачем он - представить не могу.

HTH

Onanim
()
Ответ на: комментарий от Die-Hard

> 1. Насколько этот оверхэд ДЕЙСТВИТЕЛЬНО велик? (fork() vs. vfork())

Ладно... черт с тобой... попробуем fork+_exit vs vfork+_exit :-)))

Не буду опять постить иходник (смотри мой предыдущий пост),
в vftest.c единственное изменение - вместо execl(...) теперь _exit(0).

$ time ./vftest 50000 fork
Doing 50000 iterations with do_vfork=0

real 0m6.674s
user 0m1.485s
sys 0m4.242s
$ time ./vftest 50000 vfork
Doing 50000 iterations with do_vfork=1

real 0m0.644s
user 0m0.064s
sys 0m0.505s
$

Да, сам по себе vfork рвет fork как тузик грелку.
Какая от этого практическая польза? Никакой!

Onanim
()
Ответ на: комментарий от Onanim

2Onanim:

Thanks за интересный тест.

> Какая от этого практическая польза?...

Без сравнения с pthread_create() -- небольшая. Чисто теоретическая оценка оверхэда на мечение грязных страниц при форке. Оказывается, оверхэд _действительно_ присутствует!

Ты _действительно_ не понимаешь, насколько это интересно?

Ок, а теперь попробуй перед форком поиграть количеством отожранных страниц (типа, перед форком делаем malloc() (или даже mmap() для чистоты эксперимента) с возврастающим аргументом, и проходимся по страницам, чтобы их отожрать). Не удивлюсь, если получишь линейную зависимость!

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

Вдогонку:

Если pthread_create() vs. vfork() пренебрежим, то это означает, что то ни малейшего бенефита от трэдов мы не имеем: даже если на несинтетических тестах треды будут быстрее, при реальной работе отжирание страниц будет происходить точно так же. Особенно если учесть, что mutex'ы на linux threads страшно тормозят (поскольку реализованы через сигналы), а NPTL работает через futex, которому параллельно, тред морозить, или процесс.

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

>2. Юниховые [v]fork()+exec() с Оффтопиковым аналогом (как он там называется, не помню). 
>Кому не лень, спробуйте?

Попробовал fork+exec vs. CreateProcess() , жестокие результаты получились... итак:

//testfork.c for Linux
#include <stdio.h>
#include <unistd.h>
int main(){
        int i;
        for (i=0; i<1000; ++i){
                if(fork()==0){
                        execve("./stub",NULL,NULL);
                };
        };
       return 0;
};

//testfork.c for Windows
#include <stdio.h>
#include <windows.h>
int main(){
        int i;
        STARTUPINFO stinfo;
        PROCESS_INFORMATION pinfo;
        DWORD begtime;
        begtime = GetTickCount();
        for(i=0;i<1000;++i){
                CreateProcess(".\\stub.exe",NULL,NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,
NULL,NULL,&stinfo,&pinfo);
        }
        printf("Total time %ld milliseconds",GetTickCount()-begtime);
        return 0;
};

//stub.c for both systems
#include <stdio.h>
int main(){
        return 0;
};


Результаты (4 последовательных запуска):
Linux (ядро 2.4.27 ис коропки, вывод time ./testfork):
0.00user 0.03system 0:02.19elapsed 1%CPU 
0.01user 0.15system 0:02.20elapsed 7%CPU
0.00user 0.14system 0:02.19elapsed 6%CPU
0.00user 0.09system 0:02.19elapsed 4%CPU
Linux (ядро 2.6.11 пересобранное со всякими патчами, оптимизациями и пр. и др.)
0.01user 0.19system 0:03.79elapsed 5%CPU
0.01user 0.18system 0:03.81elapsed 5%CPU
0.00user 0.18system 0:03.74elapsed 5%CPU
0.01user 0.16system 0:03.76elapsed 4%CPU 
Win2000 SP4 (время в миллисекундах):
13790
13750
13670
13790
WinXP SP2 (тоже миллисекунды):
15261
15111
15121
15202

Гораздо интереснее было бы сравнить pthreads vs CreateThread, накидайте кто-нибудь тестовый код для pthreads, а то разбираться влом.

W98
()
Ответ на: комментарий от Die-Hard


> Ты _действительно_ не понимаешь, насколько это интересно?

Не вижу ничего особо интересного в том, как этот механизм
работает именно в Linux, причем именно в той версии ядра,
на которой я запускаю тесты. Это просто деталь реализации.
На других версиях ядра может быть в чем-то по-другому. А
на Solaris и AIX - вообще может быть все не так.
О! Попробую-ка я на Solaris 8.
...
Попробовал. Разница fork+_exit vs vfork+_exit тоже есть, но
уже не в 10 раз, а всего в 4 раза.

Не, если тебя интересует kernel programming, тогда конечно
это интересно, но зачем тогда играть в "черный ящик"? Бери
исходники и читай! ;-)

> Ок, а теперь попробуй перед форком поиграть количеством отожранных
> страниц
>

Если будет время - завтра. То есть сегодня, но после ночи :-)))

Onanim
()
Ответ на: комментарий от Die-Hard

> Вдогонку:

> Если pthread_create() vs. vfork() пренебрежим, то это означает, что
> то ни малейшего бенефита от трэдов мы не имеем:

Вот тут ты меня в тупик поставил :-/
Бенефит тредов в том, что они дают несколько потоков управления в
одном и том же адресном пространстве процесса с доступом к одним
и тем же данным. Ни fork() ни vfork()такого естественно не делают.

Да, и просвети меня, как ты сравниваешь pthread_create и vfork?
Это же разные вещи. После pthread_create() ты получаешь _два_
потока управления, выполняемых параллельно.
После vfork() процесс-parent _приостанавливается_ до тех пор,
пока процесс-child не сделает exec или _exit. То есть ты
получаешь один поток. Да, после exec их опять станет два, только
уже в разных адресных пространствах. Каким же боком эти две
функции похожи и почему их надо сравнивать???

Onanim
()
Ответ на: комментарий от Onanim

Onanim (23.11.2005 2:11:09):

> Бенефит тредов в том, что они дают несколько потоков управления в одном и том же адресном пространстве процесса с доступом к одним и тем же данным.

Это == слова ...

Много лет тому назад, именно на подобных заморочках ("несколько потоков управления в одном и том же адресном пространстве процесса") сдох Малтикс и родился Юникс. Спустя много лет люди, забыв суровые уроки истории, ринулись по-новой наступать на грабли. В силу известного закон Мэрфи ("на рынке всегда побеждает самое кривое техническое решение"), нынче мы имеем суровую действительность: все распараллеливаемые решения оптимизируются прежде всего на предмет тредов. Отсюда всякие хитрые Соляркины шедулеры, критические секции, дежурные нити и т.д.

На практике, мне гораздо легче расшарить _нужные_ буфера, сохранив остальное приватным. Особенно в свете последних веяний в смысле ccNUMA: сожрав Альфу и погубив Ориджин, Интел ничего принципиально нового не родила, а Сантехнический способ бесконечного утолшения шины тоже уперся в потолок. Итого, ccNUMA -- наше будущее...

Резюме: если на последних Линуховых ядрах pthread_create() не имеет существенного преимущества перед vfork(), то я прав -- ничего принципиально нового треды не дают, посему == мастдай. Почему именно "Линуховых"? Просто потому, что остальные уже слишком зажирели, чтобы иллюстрировать концепцию.

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

Вдогонку:

> Особенно в свете последних веяний в смысле ccNUMA ...

Наверное, не очевидно для тех, кто не сталкивался...

Там проблемы с memory affinity: время доступа к "чужой" памяти может на порядки превосходить время доступа к "своей" памяти. В multithreaded подходе это обычно нивелируется кыш-когерентным кэшированием, что практически не работает для кореллированных параллельных вычислений.

Die-Hard ★★★★★
()
Ответ на: комментарий от Onanim

Onanim(*) (23.11.2005 2:11:09):

> После vfork() процесс-parent _приостанавливается_ до тех пор, пока процесс-child не сделает exec или _exit.

Кстати, да. Это -- проблема (для сравнения).

Пока дочка не освободит папу, он ни слайса не получит. Так что мой лихой тест, скорее всего, ничего не даст :(

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

Я сам что-то не понял, что за странные вещи получились...
вобщем у меня все выглядит так О_О (что это вообще такое?)

$ sudo time ./testfork
0.01user 0.18system 0:03.81elapsed 5%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+3088minor)pagefaults 0swaps

$ sudo sh -c "time ./testfork"

real    0m5.379s
user    0m0.014s
sys     0m0.295s

Под текущим юзером запускать не могу ибо стоит ограничение на кол-во процессов.

W98
()
Ответ на: комментарий от W98

2W98: Не окончил вопрос.

Linux (ядро 2.4.27) (первая строка)

user time -- negligible; system time -- 0.03 sec elapsed time -- 2.19 sec

Win2000 SP4 (первая строка) 13.8 sec

Два вопроса:

1. Исходя из того, что user + system time >> elapsed time, заключаем, что elapsed time в данном случае как раз и есть wall-clock time, т.е. то, что мы замерили бы по секундомеру. Верно?

2. GetTickCount() _действительно_ в миллисекундах? А что это за время -- юзерландское? У Линуха оно вообще нулю равно...

Die-Hard ★★★★★
()
Ответ на: комментарий от W98

2W98:

Ну, с Линухом все более - менее понятно:

процесс ничего не делает, а только отфоркивает дочек. В конце elapsed time посчитывает кумулятивное время -- так что твой тест вообще ничего не намерил :(

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

Про вопрос 1) сам не могу понять
Насчет 2) - GetTickCount - это время прошедшее со старта системы с миллисекундах, т.е это похоже хардварное время, да и судя по внешним часам проги действительно выполнялись 13 и 15 секунд соотв-но.

W98
()
Ответ на: комментарий от Die-Hard

2W98:

Такие вещи довольно трудно промерить правильно ввмду зыбкости понятия elapsed time для concurrent процессов.

Спать хочу, затра тут появишься?

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

> так что твой тест вообще ничего не намерил :(
А разве мы не временные затраты на создание новых процеесов и замеряли?

W98
()
Ответ на: комментарий от W98

> А разве мы не временные затраты на создание новых процеесов и замеряли?

Они, скорее всего, неправильно подсчитались.

Ну, типа, отфоркиваешь 100 процессов, которые спят по минуте.

Как посчитать общее время? 100 минут? Одна минута?

Для concurrent процессов надо считать _всегда_ wall clock time. А для этого надо в твоем тесте делать wait().

Die-Hard ★★★★★
()
Ответ на: комментарий от Onanim

1. Вам в форум "Development" дорога.
2. Я не программист, а админ и меня интересует работа скриптов и
   того что из них запускается (форкается).

И цель как раз и была, показать что не надо в шел злоупотреблять
циклами с вызовами внешних утилит, типа:

for var in `find / -name \*`; do
   new=`echo $var |grep -E '\.txt$' | sed 's/lala/meme/'`
   mv $var $new
done

И кроме того, показать как обстоит дело со скоростью работы 
таких скриптов на разных ОС.

З.Ы. И последнее, я вас не учу писать на С,
     а вы меня не учите писать скрипты. :-)

sdio ★★★★★
() автор топика
Ответ на: комментарий от sdio

2sdio:

> И цель как раз и была, показать что не надо в шел злоупотреблять
> циклами с вызовами внешних утилит, типа:
>

Да кто бы спорил... конечно не надо!

> З.Ы. И последнее, я вас не учу писать на С,
> а вы меня не учите писать скрипты. :-)

Ну вообще-то я тоже пишу скрипты (правда, в основном на Perl) каждый день ;-)

Да я же и не наезжаю ;-) Твой тест вполне имеет право на существование
и достаточно интересен. Просто как и с любым другим тестом надо
ясно понимать, _что_ именно ты тестируешь, иначе нельзя сделать
правильных выводов. Мои комментарии относились только к этому :-)

P.S. Удачных тебе тестов и быстрых скриптов ;-)

Onanim
()
Ответ на: комментарий от Die-Hard

Die-Hard:

> > После vfork() процесс-parent _приостанавливается_ до тех пор, пока
> > процесс-child не сделает exec или _exit.

> Кстати, да. Это -- проблема (для сравнения).

> Пока дочка не освободит папу, он ни слайса не получит. Так что мой
> лихой тест, скорее всего, ничего не даст :(

Ну блин наконец-то :-)
А я тебе о чем все время долбил?

> Много лет тому назад, именно на подобных заморочках ("несколько
> потоков управления в одном и том же адресном пространстве процесса")
> сдох Малтикс и родился Юникс. Спустя много лет люди, забыв суровые
> уроки истории, ринулись по-новой наступать на грабли. В силу
> известного закон Мэрфи ("на рынке всегда побеждает самое кривое
> техническое решение"), нынче мы имеем суровую действительность:

> На практике, мне гораздо легче расшарить _нужные_ буфера, сохранив
> остальное приватным.

Елки, ну ты-то не пионэр... откуда такой радикализм? :-/
У нас никто не отнимает fork, у нас теперь есть несколько разных
shared memory, у нас есть куча разные IPC, у нас есть pthreads.
Это просто инструменты. Для каких-то задач лучше fork + возможно
shared memory. Или fork + message queues. Или pipes. Или signals.
А для каких-то задач логичны pthreads. Где-то нужны решения с pre-
forked процессами, а где-то с тред пулами. Елки-палки, мир
многообразен, нет никакой silver bullet :-)))

Причем ведь "лучшесть" решения определяется не только performance'ом.
Для реальных программ, состоящих из сотен тысяч и миллионов строчек
вопрос сопровождения значит не меньше, а возможно и больше.
Если использование какой-то технологии позволяет сократить код,
сделать его намного более логичным и читабельным за счет потери
некотрой части производительности (в пределах допустимого для
конкретной задачи) то так и надо делать, это и есть _профессиональное_
решение. И pthreads иногда способствуют. Не надо тока пихать их
во все дыры ;-)

Onanim
()
Ответ на: комментарий от Onanim

2Onanim:

>... pthreads иногда способствуют. Не надо тока пихать их во все дыры ;-)

Дык, ведь пихают!

Насчет многообразия инструментов: они (инструменты) тоже разные бывают.

Допустим, некий биолог, всю жизнь проработавший с микроскопами и знающий о микроскопах ВСЕ, вдруг столкнулся с необходимостью забить гвоздь. Рука привычно потянулась к микроскопу...

Впоследствии, приобретя некоторый опыт, биолог пишет толстую статью о преимуществах тяжелых и твердых микроскопов. Затем он внезапно обнаруживает, что на рынке просто отсутствуют цельнолитые микроскопы без линз!

Он бросает биологию и открывает свое дело - фабрику по производству микроскопов для забивания гвоздей. Поначалу дела идут так себе, ощущается недостаток клиентов. И бывший биолог начинает мощный промоушен, взяв в банке крупный кредит.

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

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

IMHO место тредам -- на каком-нибудь соляркином веб-сервере. Конечно, всегда можно найти ситуации, когда применимы паттерны, основанные на тредах. Но, как правило (не всегда, но в большинстве случаев), найдется лучший (во всех смыслах) дизайн без тредов.

Die-Hard ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.