Киберфак – бесплатно скачать презентации PowerPoint, лекции, рефераты, шпоры, курсовые cyberfac logo
cyberfac.ru
На главную | Регистрация | Вход
  Статьи  
Главная » Статьи » Информатика » Высокоуровневые методы информатики и программирования

Методика проектирования, ориентированная на потоки данных (Delphi/C++)

Полезная статья? Пожалуйста, поставьте "+"
К содержанию

Моделирование потоков данных (процессов)
В основе данной методологии (методологии Gane/Sarson) лежит построение модели анализируемой ИС - проектируемой или реально существующей. В соответствии с методологией модель системы определяется как иерархия диаграмм потоков данных (ДПД или DFD), описывающих асинхронный процесс преобразования информации от ее ввода в систему до выдачи пользователю. Диаграммы верхних уровней иерархии (контекстные диаграммы) определяют основные процессы или подсистемы ИС с внешними входами и выходами. Они детализируются при помощи диаграмм нижнего уровня. Такая декомпозиция продолжается, создавая многоуровневую иерархию диаграмм, до тех пор, пока не будет достигнут такой уровень декомпозиции, на котором процесс становятся элементарными и детализировать их далее невозможно.

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

  1. внешние сущности;
  2. системы/подсистемы;
  3. процессы;
  4. накопители данных;
  5. потоки данных.

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

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

Номер подсистемы служит для ее идентификации. В поле имени вводится наименование подсистемы в виде предложения с подлежащим и соответствующими определениями и дополнениями.

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

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

  1. "Ввести сведения о клиентах";
  2. "Выдать информацию о текущих расходах";
  3. "Проверить кредитоспособность клиента".

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

Информация в поле физической реализации показывает, какое подразделение организации, программа или аппаратное устройство выполняет данный процесс.

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

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

Накопитель данных идентифицируется буквой "D" и произвольным числом. Имя накопителя выбирается из соображения наибольшей информативности для проектировщика.

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

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

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

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

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

Для сложных ИС строится иерархия контекстных диаграмм. При этом контекстная диаграмма верхнего уровня содержит не единственный главный процесс, а набор подсистем, соединенных потоками данных. Контекстные диаграммы следующего уровня детализируют контекст и структуру подсистем.

Иерархия контекстных диаграмм определяет взаимодействие основных функциональных подсистем проектируемой ИС как между собой, так и с внешними входными и выходными потоками данных и внешними объектами (источниками и приемниками информации), с которыми взаимодействует ИС.

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

После построения контекстных диаграмм полученную модель следует проверить на полноту исходных данных об объектах системы и изолированность объектов (отсутствие информационных связей с другими объектами).

Для каждой подсистемы, присутствующей на контекстных диаграммах, выполняется ее детализация при помощи ДПД. Каждый процесс на ДПД, в свою очередь, может быть детализирован при помощи ДПД или миниспецификации. При детализации должны выполняться следующие правила:
правило балансировки - означает, что при детализации подсистемы или процесса детализирующая диаграмма в качестве внешних источников/приемников данных может иметь только те компоненты (подсистемы, процессы, внешние сущности, накопители данных), с которыми имеет информационную связь детализируемая подсистема или процесс на родительской диаграмме;
правило нумерации - означает, что при детализации процессов должна поддерживаться их иерархическая нумерация. Например, процессы, детализирующие процесс с номером 12, получают номера 12.1, 12.2, 12.3 и т.д.

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

Миниспецификация является конечной вершиной иерархии ДПД. Решение о завершении детализации процесса и использовании миниспецификации принимается аналитиком исходя из следующих критериев:
наличия у процесса относительно небольшого количества входных и выходных потоков данных (2-3 потока);
возможности описания преобразования данных процессом в виде последовательного алгоритма;
выполнения процессом единственной логической функции преобразования входной информации в выходную;
возможности описания логики процесса при помощи миниспецификации небольшого объема (не более 20-30 строк).

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

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

Потоки данных в Delphi

В Delphi есть несколько видов потоков – файловый поток, поток в памяти, поток связанный с handle объекта, строковый поток и т.д. Все они унаследованы от своего абстрактного предка TStream. Разобравшись с ним вы сможете единообразно работать с любыми другими потоками.

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

  1. function Read(var Buffer; Count: Longint): Longint; virtual; abstract; - читает данные из потока в буфер;
  2. function Write(const Buffer; Count: Longint): Longint; virtual; abstract; - пишет данные в поток;
  3. function Seek(Offset: Longint; Origin: Word): Longint; virtual; abstract; - устанавливает позицию в потоке.

Как видите все очень просто. Суть же в том, что с использованием потоков можно единообразно работать с памятью, файлами, строками и т.д.

Есть и пара просто полезных функций:

  1. function CopyFrom(Source: TStream; Count: Longint): Longint; - эта функция копирует часть или весь поток из другого потока. Этим методом, например, очень удобно копировать файлы. Есть мнение, что работа с потоками, быстрее работы с файлами. К сожалению у меня не было возможности проверить это утверждение…
  2. procedure SaveToFile(const FileName: string); - позволяет сохранить участок памяти в дисковый файл.

Теперь мы подошли к одному из самых мощных, полезных и удобных решений – инкапсуляции потоков в Delphi. Понятие потока представлено программистами Borland в виде абстрактного класса TThread Каждый разработчик может унаследовать от него свой поток, наделив его нужной функциональностью. Все проблемы по управлению потоками, их синхронизации и т.д. остаются на долю VCL. В рамках данной статьи я не берусь подробно описать и объяснить все механизмы и тонкости задействованные при работе с потоками и все же отошлю вас к литературе данной в конце статьи, а сам же дам лишь обзор потоков.

Итак, когда и зачем используются потоки? Что это такое? Потоки – это объекты, которым процессор выделяет время. Обратите внимание, не процессам или программам, а порожденным им потокам. Так что любая программа содержит в себе хотя бы один поток. Он называется главным. С появлением потоков появилась возможность отдавать для решения каждой задачи ровно столько ресурсов, сколько ей нужно. Для этого используется понятие приоритета потока. Каждый процесс имеет свой приоритет (от фонового до реального времени). В рамках процесса существуют потоки, приоритетом которых (потоков) может управлять процесс. Таким образом приоритет может иметь значение от 0 до 31. Следует заметить, что программы написанные в Delphi по умолчанию порождают процесс с нормальным приоритетом (он может быть переднего или заднего плана, в зависимости от активности задачи и меняться от 9 до 7). Процессы реального времени используются крайне редко.

Чтобы сделать свой поток, вам нужно унаследовать свой класс от объекта TThread. Это можно сделать из меню File -> New… Будет создан модуль с заготовкой для класса. Все что вам нужно сделать – перекрыть метод Execute. Для этого его нужно объявить как override и наделить нужной функциональностью.

При написании метода Execute нужно учесть следующее: поток работает параллельно с основным потоком программы и может обращаться к каким-то элементам или компонентам  также параллельно с основным потоком. Чтобы избежать этого, нужно использовать метод Synchronize. В его параметре следует указать действия, производимые с «общими» объектами. Например

Synchronize(MainForm.Label1.Caption:=’Hello!’);

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

Процесс может находиться в двух состояниях – выполняться или быть приостановленным. За это отвечают методы

procedure Suspend;
procedure Resume;

Также процесс может самоуничтожаться по завершении - свойство FreeOnTerminate.

Метод
function WaitFor: LongWord; ожидает завершения потока.

C++ - Потоки в Win32

Любой поток (thread) состоит из двух компонентов:
- объекта ядра, через который ОС управляет потоком. Там же хранится статистическая информация о потоке.
- Стека потока, который содержит параметры всех функций и локальные переменные, необходимые потоку для выполнения кода.
Потоки всегда создаются в контексте какого-либо процесса, и вся их жизнь проходит только в его границах. На практике это означает, что потоки исполняют код и манипулируют данными в адресном пространстве процесса. Если два или более потока выполняются внутри одного процесса, они делят одно адресное пространство.

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

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

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

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

DWORD WINAPI ThreadFunc(PVOID pParam)
{
DWORD dwResult = 0;
.........
return dwResult;
}


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

Когда поток закончит свое исполнение, он вернет управление системе, память, отведенная под его стек, будет освобождена, а счетчик пользователей его объекта ядра "поток" уменьшится на 1. Когда счетчик обнулится, этот объект ядра будет разрушен.

Для создания своего потока необходимо использовать функцию CreateThread:

HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId);


При каждом вызове этой функции система создает объект ядра (поток). Это не сам поток, а компактная структура данных, которая используется операционной системой для управления потоком и хранит статистическую информацию о потоке.

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

CreateThread - это Windows-функция, создающая поток. Если вы пишете код на С/С++ не вызывайте ее. Вместо нее Вы должны использовать _beginthreadex из библиотеки Visual C++. Почему это так важно в наших следующих выпусках.

Параметры функции CreateThread.

  1. LpThreadAttributes - является указателем на структуру LPSECURITY_ATTRIBUTES. Для присвоения атрибутов защиты по умолчанию, передавайте в этом параметре NULL.
  2. DwStackSize - параметр определяет размер стека, выделяемый для потока из общего адресного пространства процесса. При передаче 0 - размер устанавливается в значение по умолчанию.
  3. LpStartAddress - указатель на адрес входной функции потока.
  4. LpParameter - параметр, который будет передан внутрь функции потока.
  5. DwCreationFlags - принимает одно из двух значений: 0 - исполнение начинается немедленно, или CREATE_SUSPENDED - исполнение приостанавливается до последующих указаний.
  6. LpThreadId - Адрес переменной типа DWORD в который функция возвращает идентификатор, приписанный системой новому потоку.

Завершение потока
Поток можно завершит четырьмя способами:

  1. функция потока возвращает управление (рекомендуемо);
  2. поток самоуничтожается вызовом функции ExitThread;
  3. другой поток процесса вызывает функцию TerminateThread;
  4. завершается процесс, содержащий данный поток.

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

Функция потока, возвращая управление, гарантирует корректную очистку всех ресурсов, принадлежащих данному потоку. При этом:

  1. - любые С++ объекты, созданные данным потоком, уничтожаются соответствующими деструкторами;
  2. - система корректно освобождает память, которую занимал стек потока;
  3. - система устанавливает код завершения данного потока. Его функция и возвращает;
  4. - счетчик пользователей данного объекта ядра (поток) уменьшается на 1.

При желании немедленно завершить поток изнутри используют функцию ExitThread(DWORD dwExitCode). При этом освобождаются все ресурсы ОС, выделенные данному потоку, но С С++ ресурсы (например, объекты классов С++) не очищаются. Именно поэтому не рекомендовано завершать поток, используя эту функцию. Если же вы ее использовали, то кодом возврата потока будет тот параметр, который вы передадите в данную функцию.

Как и для CreateThread для библиотеки Visual C++ существует ее аналог _endthreadex, который и стоит использовать. Об причинах в следующем выпуске. Если появилась необходимость уничтожить поток снаружи, то это моет сделать функция TeminateThread.

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

При завершении процесса происходит следующее.
Завершение потока происходит принудительно. Деструкторы объектов не вызываются, и т.д. и т.д. При завершении потока по такой причине, связанный с ним объект ядра (поток) не освобождается до тех пор, пока не будут закрыты все внешние ссылки на этот объект.


Категория: Высокоуровневые методы информатики и программирования | Добавил: Ni-Cd (01 Декабря 2011)
Просмотров: 2044 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
  Полезные материалы  

В нашем каталоге файлов можно найти много полезной информации. Также советуем заглянуть в каталог статей: в нем есть полезные статьи по темам: Экономика предприятия, Общая экономика, Финансы и Кредит, также Словарь терминов по экономике, Маркетинг, Бухучет и Мировая экономика
Также есть полезная страница Факультеты МИФИ, которая расскажет о том, какие есть в МИФИ факультеты.
Меню
 

Навигация
Высокоуровневые методы информатики и программирования [28]
Информатика и программирование [34]
Информационные системы в экономике [36]
Языки программирования и методы трансляции [15]
Алгоритмизация и программирование [61]
 

Поиск
 

Онлайн
Онлайн всего: 1
Гостей: 1
Пользователей: 0
 

Статистика


Рейтинг@Mail.ru

 


2007 - 2022 © Ni-Cd. All Rights Reserved