День 14. Разработка многопоточной программы.

День 14. Разработка многопоточной программы.

Интересная статья. Создание дистрибутива. Прододжение совершенствования многопоточной программы.

Статья о современном состоянии языков программирования

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

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

Очень правильно сказано. Действительно в статьях засилье этой парадигмы. Она употребляется к месту и не к месту.

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

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

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

Поэтому разработчики Java, к примеру, вместо того, чтобы использовать уже существующие компоненты, решают включить в своё решение всё, что "может понадобиться", чтобы весь компьютерный мир оказался охваченным Java. – отлично сказано! Это и есть причина раздутости многих пакетов ПО, как инструментальных, так и для конечного пользователя. Это путь интенсивного развития. Когда вместо построения четкой, стройной модели для решения четко ограниченного круга задач из ПО делают свалку всего, сваливая на пользователя работу по разгребанию этой свалки по ее системпатизации.

Частный коммерческий успех объектов и наш развивающийся в последнее десятилетие роман с большим бизнесом вылились в остановку изучения и разработки альтернативных языковых подходов и парадигм в компьютерной науке. ... Безумие большого бизнеса конца прошлого века ослепило исследователей и привело к тому, что на их взгляд, то, что существует в сфере ООП сегодня, настолько близко к идеалу, что это бесспорно. ... (Томас Кун в своей книге "Структура научных революций" показал, что принятие единой парадигмы, в конце концов, обязательно приведёт к новой революции).

объектно-ориентированные языки потеряли простоту, а можно сказать и чистоту, которая особенно их отличала в плане выразительной силы и творческой мощи.

несмотря на ясное понимание пионерами ОО природы разработки программ, нынешнее поколение их преемников более озабочено философией тщательного планирования, монументального дизайна, идеей охватить всё, "всеведением", взятым из теологии Бэббиджа

Те, кто пришли в восторг от ООП, заслонили дорогу и не сходят с неё, не давая другого выбора — не по злому умыслу, а от богатства — и вот, ресурсы, которые могли быть использованы для альтернативных исследований, иссякают. Но однажды их богатство исчезнет, поскольку будет растрачено на сталкивание с дороги других

Что и говорить письмо получилось неоднозначным, но оно делает попытку вскрыть накопившиеся проблемы, и указать несколько другой путь их решения. Интереснее было читать отзывы на эту статью.

довольно сложно автору показать недостатки таких языков (не их реализаций) как Smaltalk, Forth - их самый большой недостаток - непопсовость и "немодность" (может поэтому качественных их реализаций от софтверных "авторитетов" практически нет - это и понятно: деньги приносит массовый потребитель, а толпе не нужна классическая музыка, толпа хочет Бритни Спирс и Киркорова

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

Если еще проще - в зависимости от того, окупятся ли потери времени на изучение нового языка выигрышем от уменьшения срока разработки.

Императивные языки хороши на небольших участках. Глобальные задачи лучше описывать на декларативных языках или их гибрдах. Например HTML,XUL,etc. - декларативные языки. SQL, make(котоый в Makefile) - гибридные. C, Java, perl, ML, etc. - императивные (с некоторыми елементами декларативности - полностю императивный только машинный код). ... Мне намного легче поставить цель и описать какие цели от нее зависимы и как ее достичь, чем рассказывать каждому отдельному обьекту куда ему ити. Кстати, почему-то коефециент повторного использования кода в makefile-ах намного выше 50%, в отличие от всех остальных языков, где он не превышает 5%. Возможно потому, что цели очень часто бывают одинаковыми, в отличие от путей их достижения. – Неплохо описано...

Кто-то в середине прошлого века сказал: "Я видел скульптуры Фидия и памятник Юрию Долгорукому. Если это прогресс, то мне хочется выброситься из окна". Так вот "чел", похоже, испытывает похожие ощущения после возвращения в "мир ИТ". Не потому, что он против нового вообще, а потому, что ему есть с чем сравнивать.

Создание дистриубтива SP-Forth

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

На первом этапе, на пробном, было решено достигать следующих целей:

Как отдаленная, но наиболее привлекательная цель видится создание стартового дистрибутива, с подгрузкой свежих обновлений из репозитария, чтобы постоянно свежую версию языка. Идея полностью аналогична портежам Linux-дистрибутива Gentoo или FreeBSD. Зачатки в первом дистрибутиве уже есть – в него включен скрипт cvs\update.bat Правда я его еще толком не тестировал.

В качестве инструментария для создания инталляции использовался NSIS Известный и широко используемый. А также редактор инсталляционных скриптов HM NIS Edit

Полученный инсталляционный скрипт можно взять здесь А сам дистрибутив здесь

Как и первый блин ... далек от идеала. По мере появления идей будет дорабатываться.

Тестирование дистрибутива

Попробовал перенести полученный дистрибутив на другую машинку. Вылезли ошибки. В основном из-за ошибок в праке путей.

Но самое гланое не в этом. Очень не хватает среды разработчика Да можно настроить Far, указать какие плугины к нему цеплять, где их брать, как настривать... Но это все подготовительные операции, которе не только можно, но и нужно автоматизировать! Но тут несколько моментов: а) лицензоинная политика авторов плугинов б) их установка или обновление в автоматическом режиме...

Опрообован принцип обновления дистрибутива из CVS-репозитария. Идея на практике оказалась не очень:

Вывод, CVS это не тот инструмент для задачи обновления дистрибутива. Ведь эта задача сводиться к:

Т.е. обновление сводится фактически к синхронизации на уровне файлов. Т.е. возможности CVS здесь излишни. Можно и нужно использовать более простой, более эффективный, специализированный инструмент. В мире UNIX это команда merge В мире WinXX можно указать nnbackup Кстати, тоже написанное на SP-Forth :) nnBackup бесплатен для граждан стран бывшего СССР при условии частного и некоммерческого использования.

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

А идея проста: репозитарий – эталонная рабочая система, с которой синхронизируются остальные дистрибутивы.

Видно, что я здесь не рассматриваю вопрос версионности, их сохранения, отката, ведения и проч. Но, как мне сейчас кажется, для этой задачи это излишне.

Зато появляется возможность сделать так называемый стартовый дистрибутив – минимальная система, которая во время установки скачивает с сайта и устанавливает самую свежую версию. Идея тоже не нова, многие дистрибутивы Linux именно так и построены.

Панель индикаторов. Продолжение

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

Для наших, довольно не сложных целей, лучше воспользоваться вторым подходом.

Для переменных потоков лучше использовать переменные, создаваемые командой USER Ее использование анлогично VARIABLE Переменная объявляется вне объявления слова, вызов по имени приводит к тому, что на стек кладется адрес.

 USER aaa
: TestA
    78 aaa !  ;  \ закинули значение
: TestB
    aaa @ .   ;  \ вызвали содержимое и на печатали его
\ Тестируем
 TestA TestB

Чтобы унифицировать работу с экраном, разработаем низкоурвоневые слова, которые будут выводить на экран в нужное место указанную строку с учетом флага занятости.

Для отслеживания занят или свободен ресурс (экран) введем глобальную переменную ЭкранЗаблокирован которая ббудет выполнять рол флага. Если эта переменная содержит значение 0, то ресурс свободен, если 1 – занят.

0 VALUE ЭкранЗаблокирован \ первоначально, экран не кем не занят

Выводить на экран может только слово НаЭкран Оно приниммает строку и координаты где ее печатать. Она отслеживает блокировку и если возможно, то печатает на экране переданную ей строку. Вот ее алгоритм:

Введем низкоуровневые слова для работы с атрибутами текста и соотвествующие локальные(!) переменные для каждого потока. Иначе атрибуты станут гл обальными :(

0 USER ШрифтЦветФона \ по умолчанию фон черный
7 USER ШрифтЦвет     \ а символы -- белые

: =ШрифтЦветФона ( цвет – ) ШрифтЦветФона ! ; : =ШрифтЦвет ШрифтЦвет ! ;

Теперь само слово для печати. Для наших потребностей, будем полагать что строка задается как константа в теле программы конструкцией S" ...."

: НаЭкран ( c-addr u x y – )
  100   \ Кол-во попыток
 BEGIN ЭкранЗаблокирован @ WHILE \ Заблокирован?
     1 PAUSE                      \ Жду....
 DUP 0= IF                    \ Превысили предел ожидания
 DROP 2DROP 2DROP         \ чисти стек
 EXIT                     \ выходим
 THEN
 REPEAT DROP

1 ЭкранЗаблокирован ! \ Блокирую экран ШрифтЦвет ШрифтЦветФона TEXT-ATTR \ Атрибуты текста AT-XY \ курсор TYPE \ вывод строки 0 ЭкранЗаблокирован ! \ разблокировал ;

Однако в процессе тестирования, некоторые моменты были пересмотрены. Так я отказался от слов =ШрифтЦветФона и =ШрифтЦвет они тривиальны, и много проще оказалось оперировать непосредственно самими переменными. Отказался от использования VALUE несмотря на то, что использование техники обращения по имени переменной к ее значению удобнее, гораздо, удобнее и практичнее выдерживать единый стиль – обращение как к локальным, так и глобальным переменным должно проходить по одним правилам.

Оказалось довольно удобным вытянуть исходный текст слова TEXT-ATTR и модифицировать его под свои нужды, при этом упростился и сам алгоритм. В итоге получилось слово АтрибутыТекста и ОчиститьЭкран Причем в случае последнего слова это более очевидно.

Поиск слова для выдачи случайного слова уже происходила быстрее – задал поиск в файлах *.f слова RND Главная трудность здесь – угадать с названием слова :(

В итоге получилась вот такая тестовая программа.

  \ Тестирование блокировки экрана при многозадачности 
 REQUIRE AT-XY ~day/common/console.f
 REQUIRE CHOOSE lib/ext/rnd.f

\ -------------- Библиотечный функции ----------------------- VARIABLE ЭкранЗаблокирован \ первоначально, экран не кем не занят USER ШрифтЦветФона \ по умолчанию фон черный USER ШрифтЦвет \ а символы -- белые

\ Устанавливает текущие атрибуты текста \ Доработанный TEXT-ATTR из ~day\common\console.f : АтрибутыТекста ( – ) ШрифтЦветФона @ 16 * ШрифтЦвет @ + H-STDOUT SetConsoleTextAttribute DROP ; \ Вместо стандартного CLS -- в консоли на ХР не работает : ОчиститьЭкран 0 H-STDOUT SetConsoleTextAttribute DROP \ черный фон и буквы 500 0 DO \ забиваю весь экран ." " LOOP 7 H-STDOUT SetConsoleTextAttribute DROP \ белые буквы и черный фон ; : НаЭкран ( c-addr u x y – ) 100 \ Кол-во попыток BEGIN ЭкранЗаблокирован @ WHILE \ Заблокирован? 1 PAUSE \ Жду.... DUP 0= IF \ Превысили предел ожидания DROP 2DROP 2DROP \ чисти стек EXIT \ выходим THEN 1- \ уменьшил счетчик попыток REPEAT DROP

1 ЭкранЗаблокирован ! \ Блокирую экран АтрибутыТекста AT-XY \ курсор TYPE \ вывод строки 0 ЭкранЗаблокирован ! \ разблокировал ;

\ --------------- Создаю потоки и тестирую ------------------ : СлучЦветГамма 16 CHOOSE ШрифтЦветФона ! 16 CHOOSE ШрифтЦвет ! ;

:NONAME \ именно через это ключевое слово 0 ШрифтЦветФона ! 7 ШрифтЦвет ! BEGIN \ бесконечный цикл СлучЦветГамма S" task1" 10 5 НаЭкран 200 PAUSE AGAIN ; TASK: t1 \ имя образу (?) задачи

:NONAME 0 ШрифтЦветФона ! 7 ШрифтЦвет ! BEGIN СлучЦветГамма S" task2" 10 20 НаЭкран 200 PAUSE AGAIN ; TASK: t2

ОчиститьЭкран 0 t1 START \ На стеке ИД потока 0 t2 START

Программа очищает экран и выводит два слова task1 и task2, которые переливается цветами. Каждым словом упраляет отдельный поток. Выход из программы по ctrl+C

Простейший строковый редактор

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

Задачи этого редактора просты – считывать с клавиатуры символы, печатные отображать, выделять служебные и выполнять некоторые операции по редактирвоанию текста. При получении команды "ОкончаниеВвода" передать сформированную строку на интерпретацию Форту.

Алгоритм здесь следующий:

Передача инструкций интерпретатору

Основной вопрос – как передать интерпретатору и затаставить его выполнить строку с параметрами? После получасового лазиния по исходникам, по встроенной справке, по отсканированной книге Баранова и беспрерывного тестирования, выяснил что это слово EVALUATE Вот пример интерактивного его тестирования.

> S" 1 2 + . " EVALUATE
> 3 ok

Сбивала с толку его стековая нотация ( i*x c-addr u – j*x ) Что обозначает i*x ? Не знаю. Зато пример работает. Потмо полез в стандарт, и нашел расшифровку обозначений в таблице 3.1 "Типы данных". Блин, можно было в справку включить. Ниже привожу ее.

    Символ             Тип данных                    Размер на стеке
    -------------------------------------------------------------------------
    flag               флаг                          1 ячейка
    true               флаг истина                   1 ячейка
    false              флаг ложь                     1 ячейка
    char               символ                        1 ячейка
    n                  число со знаком               1 ячейка
    +n                 не отрицательное число        1 ячейка
    u                  без знаковое число            1 ячейка
    n|u (1)            число                         1 ячейка
    x                  любая ячейка                  1 ячейка
    xt                 идентификатор исполнения      1 ячейка
    addr               адрес                         1 ячейка
    a-addr             выровненный адрес             1 ячейка
    c-addr             символьно-выровненный адрес   1 ячейка
    d                  число со знаком две-ячейки    2 ячейки
    +d                 не отрицат. число две-ячейки  2 ячейки
    ud                 беззнаковое число две-ячейки  2 ячейки
    d|ud (2)           число две-ячейки              2 ячейки
    xd                 любая пара ячеек              2 ячейки
    colon-sys          компиляция определения        определяемое реализацией
    do-sys             do-loop структуры             определяемое реализацией
    case-sys           CASE структуры                определяемое реализацией
    of-sys             OF структуры                  определяемое реализацией
    orig               источник потока-управления    определяемое реализацией
    dest               назначение потока-управления  определяемое реализацией
    loop-sys           loop-control параметры        определяемое реализацией
    nest-sys           вызовы определения            определяемое реализацией
    i*x, j*x, k*x (3)  любой тип данных              0 или более ячеек
    -------------------------------------------------------------------------

(1) Может быть число со знаком или без знака в зависимости от контекста. (2) Может быть две-ячейки число со знаком или две-ячейки число без знака в зависимости от контекста. (3) Может быть неопределенное число входов стека неопределенного типа. Для примеров использования, см. 6.1.1370 EXECUTE, 6.1.2050 QUIT.

Литература, это отдельная песня... Большинство слов, а, особенно для этого случая, в стандарте 94 помечены как устаревшие и не рекомендуемые к использованию... То есть проку не очень. Ну попытался я поиграться со словами TIB #TIB >IN чтобы переключить их на сохраненную в памяти строку, только завесил программу...

С обработкой ошибок, то есть не найденное слово, еще что-то тоже разобрался не очень быстро, но нашел в файле samples\win\spfwc\debug более-менее понятное использование в слове eval_debug_statements. Мой тестовый работающий пример, приобрел вид:

: TTT
 S" 33  DaUP + . " ['] EVALUATE CATCH
 IF ." Ошибка в команде" CR 2DROP
 THEN
;
TTT

Вот такая простейшая обработка... Главная особенность – CATCH требует адрес прверяемого слова, поэтому перед EVALUATE и стоит слово [']

В приципе можно считать эту задачу решенной.

<<< Предыдущий Начало   Следующий >>>
Copyright © Alex Furashev 2004

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

Hosted by uCoz