Показать сообщение отдельно
Старый 26.03.2011, 12:50   #3
Paul Kellerman
Gold Member
 
Регистрация: 25.06.2005
Адрес: F000:FFF0
Сообщений: 1,804
По умолчанию

Что же, прошло достаточно много времени с момента поднятия данной темы.
Хочу поделиться простеньким примером программы, выполняющей "длитель-
ные расчеты", послушать мнения и предложения спецов в программировании.

Суть самой программы простейший: вводите количество испытаний n и веро-
ятность успеха в отдельном испытании p, ну и запускаете расчет, в котором
простым итерационным способом проводится n испытаний и подсчитывается
количество успехов. Параметр n, целое число в пределах от 0 до 999999999,
а p, действительное число (и в качестве разделителя целой и дробной части
используется точка, а не запятая), от 0 до 1. Очевидно, при большом n испы-
тания и подсчет успехов могут затянуться, поэтому требуется особый подход.

Программа написана с использованием традиций объектно-ориентированного
программирования и событийно-ориентированного подхода в Delphi, и к этому
всему добавлен многопоточный подход со всеми вытекающими особенностями.
Исходный код сосредоточен в двух модулях: основном (lm_main.pas) и матема-
тическом (lm_math.pas). Исходный код достаточно подробно закомментирован.

Основные особенности моего подхода в данной программе:

- Математическая обработка выполняется в отдельном потоке SolverThread, ко-
торый запускается в обработчике события нажатия кнопки "Пуск". Далее либо
он самостоятельно завершается (все испытания проведены) либо прерывается
пользователем кнопкой "Стоп", при этом для события завершения потока есть
свой отдельный обработчик, где в частности выводятся результаты испытаний.

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

- Для периодического отображения текущего состояния (хода вычислений) мат-
аппарата применен следующий прием. В программе создается специальный тай-
мер UpdateTimer, который с периодом 20 миллисекунд срабатывает и операцион-
ная система посылает главному окну программы Windows-сообщение WM_TIMER.
Это сообщение обрабатывается в главной "оконной" процедуре WndProc, привя-
занной к основному окну программы. При обработке сообщений WM_TIMER, про-
веряется активен ли данный момент поток матобработки, и если да, то считыва-
ется структурная переменная состояния матобработки, вычисляется "прогресс"
(доля завершенности) матобработки и обновляется соответ. полоса прогресса.

P.S. На всякий случай скажу, что это не лучший пример моего программирова-
ния, сам я оцениваю свой подход к реализации сложных расчетов на "четыре".
Некоторые проверки и оптимизации я намеренно удалил, чтобы пример был как
можно проще и короче, но даже с учетом этого получилось около 450 строк
Вложения
Тип файла: zip longmath.zip (457.6 Кб, 6 просмотров)

Последний раз редактировалось Paul Kellerman; 26.03.2011 в 14:21.
Paul Kellerman вне форума   Ответить с цитированием
Реклама