Главная страница Цифровые системы [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31] [32] [33] [34] [35] [36] [37] [38] [39] [40] [41] [42] [43] [44] [45] [46] [47] [48] [49] [50] [51] [52] [53] [54] [55] [56] [57] [58] [59] [60] [61] [62] [63] [64] [65] [66] [67] [68] [69] [70] [ 71 ] [72] [73] [74] [75] [76] [77] [78] [79] [80] [81] [82] [83] [84] [85] [86] [87] [88] [89] [90] к общему ресурсу защищен с помощью семафора mutex, при этом продолжается только один процесс. Это решение проще, чем основанное только на семафорд Оно также более эффективно, поскольку процессы проверяют условия только тог да, когда это имеет смысл, т. е. после изменения значения соответствующих пере менных. Важный тип события в системах реального времени связан с внешними прерываниями. Программа обработки - обработчик прерываний - ждет прерывания. Когда оно происходит, исполнение обработчика возобновляется. 10.5. Обмен информацией между процессами 10.5.1. Общие области памяти Взаимодействующие процессы нуждаются в обмене информацией. Поэтому многозадачная операционная система должна обеспечивать необходимые для этого средства. Обмен данными должен быть прозрачным для процессов, т. е. передаваемые данные не должны изменяться, а сама процедура должна быть легко доступна для каждого процесса. Простейший метод - использование общих областей памяти, к которым разные процессы имеют доступ для чтения/записи. Очевидно, что такая область представляет собой разделяемый ресурс, доступ к которому должен быть защищен, например, семафором. Главное преимущество общих областей памяти заключается в том, что к ним можно организовать прямой и мгновенный доступ, например один процесс может последовательно записывать поля, а другой затем считывать целые блоки данных. При программировании на машинном уровне общие области размещаются в оперативной памяти по известным адресам. В языках высокого уровня вместо этого используются глобальные переменные, доступные нескольким дочерним процессам. Так, например, происходит при порождении потоков, для которых переменные родительского процесса являются глобальными и работают как общие области памяти. В случае возможных конфликтов доступа к общим областям они должны быть защищены семафорами. 10.5.2. Почтовые ящики Другой метод, позволяющий одновременно осуществлять обмен данными и сида ронизацию процессов, - это почтовые ящики. Почтовый ящик представляет со ои структуру данных, предназначенную для приема и хранения сообщений (рис. 1 • > Для обмена сообщениями различного типа можно определить несколько почтовы ящиков. отправка сообщения почтовый ящик сообщение 1 сообщение 2 выемка сообщения Во многих операционных системах почтовые ящики реализованы в виде логичес-,j,jX файлов, доступ к которым аналогичен доступу к физическим файлам. С почто-зыми ящиками разрешены следующие операции: создание, открытие, запись/чтение сообщения, закрытие, удаление. В некоторых системах поддерживаются дополни-.ельные служебные функции, например счетчик сообщений в почтовом ящике или чтение сообщения без удаления его из ящика. Почтовые ящики размещаются в оперативной памяти или на диске и существуют пишь до выключения питания или перезагрузки. Если они физически расположены на диске, то считаются временными файлами, уничтожаемыми после выключения системы. Почтовые ящики не имеют имен подобно реальным файлам - при создании им присваиваются логические идентификаторы, которые используются процессами при обращении. Для создания почтового ящика операционная система определяет указатели на область памяти для операций чтения/записи и соответствующие переменные для защиты доступа. Основными методами реализации являются либо буфер, размер которого задается при создании ящика, либо связнный список, который, в принципе, не накладывает никаких ограничений на число сообщений в почтовом ящике. В наиболее распространенных реализациях процесс, посылающий сообщение, записывает его в почтовый ящик с помощью оператора, похожего на оператор записи в файл put mailbox (#1, message) Аналогично, для получения сообщения процесс считывает его из почтового ящика с помощью оператора вида get mailbox (# 1, message) Запись сообщения в почтовый ящик означает, что оно просто копируется в указанный почтовый ящик. Может случиться, что в почтовом ящике не хватает места для хранения нового сообщения, т. е. почтовый ящик либо слишком мал, либо хранящиеся в нем сообщения еще не прочитаны. При чтении из почтового ящика самое старое сообщение пересылается в принимающую структуру данных и удаляется из ящика, т. е. почтовый ящик - это пример классической очереди, организованной по принципу FIFO. Операция чтения из пустого - ящика приводит к различным результатам в зависимости от способа реализа-блок- возвращается пустая строка (нулевой длины), либо операция чтения тельГ" получения сообщения. В последнем случае, чтобы избежать нежела- i имеющихся в данный момент в ящике. °-5.3. Каналы Ний процесса, необходимо предварительно проверить число сообще- ами. нал {pipe) представляет собой средство обменаданными между двумя процес- из которых один записывает, а другой считывает символы. Этот механизм был v оначально разработан для среды UNIX как средство перенаправления входа и одапроцесса. В ОС UNIX физические устройства ввода/вывода рассматривают файлы, а каждая программа имеет стандартное устройство ввода (вход) и стан- Рис. 10.8. Работа почтового ящика В русской литературе также используется термин "конвейер". - Примеч. ред. дартное устройство вывода (выход), клавиатуру и экран монитора - можно перео ределить, например, с помощью файлов. Когда выход одной программы перенап ляется на вход другой, создается механизм, называемый каналом (в операционн" системах для обозначения канала используется символ "j"). Каналы применяются" операционных системах UNIX, OS/9 и Windows NT в качестве средства связи меж-" процессами (программами). Каналы можно рассматривать как частный случай почтового ящика. Различие между ними заключается в организации потока данных - почтовые ящики работают с сообщениями, т. е. данными, для которых известны формат и длина, а каналы прин ципиально ориентированы на неструктурированные потоки символов. В некоторых операционных системах, однако, возможно определить структуру передаваемых по каналу данных. Обычно процесс, выполняющий операцию чтения из канала, ждет пока в нем не появятся данные. В настоящее время операционные системы включают методы, позволяющие избежать блокировки программы, если это нежелательно с точки зрения ее логики. Операции над каналами эквивалентны чтению/записи физических файлов. Они включают функции, как определить, открыть, читать, записать, закрыть, удалить. Дополнительные операции могут устанавливать флаги режима доступа, определять размер буфера и т. д. Благодаря тому что ввод/вывод в файл и на физические устройства и вход/выход процессов трактуются одинаково, каналы являются естественным средством взаимодействия между процессами в системах "клиент-сервер". Механизм каналов в UNIX может в некоторых случаях зависеть от протокола TCP/IP, а в Windows NT каналы работают с любым транспортным протоколом. Следует иметь в виду, что внешне простой механизм каналов может требовать больших накладных расходов при реализации, особенно в сетевых системах (разделы 10.2.3 и 10.6.7). 10.5.4. Удаленный вызов процедур Модель "клиент-сервер" построена на обмене сообщениями "регулярной структуры, которые можно передавать, например, через механизм каналов. Однако основной процедурой обмена данными и синхронизации в среде "клиент-сервер" является удаленный вызов процедур (Remote Procedure Call - RPC)-Последний может рассматриваться как вызов подпрограммы, при котором операционная система отвечает за маршрутизацию и доставку вызова к узлу, где находится эта подпрограмма. Нотация обращения к процедуре не зависит от того, явля ется ли она локальной или удаленной по отношению к вызывающей программе. Это существенно облегчает программирование. В системе реального времени существенно, является RPC блокирующим или нет. Блокирующий RPC не возвращает управление вызывающему процессу, пока не закончит свою работу, например пока не подготовит данные для ответа. Неблокирующие RPC возвращают управление вызывающей процедуре по истечении некоторого времени (timeout) независимо от того, завершила ли работу вызы ваемая процедура; в любом случае вызывающая программа получает коД. идентифицирующий результат выполнения вызова, - код возврата. Таким образом, неблокирующие RFC имеют важное значение с точки зрения гарантии живу ести системы. 5.5. Сравнение методов синхронизации и обмена данными }ia первый взгляд может показаться, что основные задачи, связанные с парал-,льным программированием, взаимным исключением, синхронизацией и коммуни- циями между процессами, имеют мало общего, но в сущности - это просто разные дособы достижения одной цели. Методы синхронизации можно использовать для 1-анизации взаимного исключения и коммуникаций. Аналогично, с помощью тех-jHKH коммуникаций между процессами можно реализовать функции синхронизации взаимного исключения процессов. Например, семафор эквивалентен почтовому ящику, в котором накапливаются сообщения нулевой длины, - операции signal и wait эквивалентны операциям put и get почтового ящика, а текущее значение семафора эквивалентно числу помещенных в почтовый ящик сообщений. Аналогично можно организовать взаимное исключение и защиту ресурсов с помощью почтовых ящиков. В этом случае сообщение выполняет функцию маркера". Процесс, получивший этот "маркер", приобретает право входить в критическую секцию или распоряжаться ресурсами системы. При выходе из секции или освобождении ресурса процесс помещает "маркер" в почтовый ящик. Следующий процесс читает из почтового ящика, получает "маркер" и может войти в критическую секцию. Связь между разными подходами имеет практическое значение в том случае, если в системе применяется только один из них, а все остальные нужно строить на его основе. Современные операционные системы, поддерживающие многозадачный режим и операции в реальном времени, применяют все упомянутые методы. Передача сообщений и доступ к общим областям памяти медленнее, чем проверка и обновление семафора и переменной события, и требует дополнительных накладных расходов. Если есть выбор «ежду различными методами синхронизации и взаимодействия, следует использовать тот из них, который лучше решает конкретную проблему - результирующая программа будет понятнее и, возможно, быстрее работать. Кроме того, весьма важно оценить, насколько эффективно в имеющейся программной среде реализуются конкретные реше-чия. Следует избегать незнакомых и неестественных конструкций. В распределенных системах всегда существует риск потерять сообщение в сети. Если сетевая система сконфигурирована так, что она контролирует правильность "Федачи сообщения и имеются средства для повторной передачи утраченных сообщений, то прикладная программа не должна осуществлять дополнительные провер-и. Обычно нижний уровень операционной системы и процедуры сетевого интерфейса передают на более высокий уровень код возврата, который прикладная программа должна проверить, чтобы убедиться, была ли попытка успешной или нет, при необходимости повторить ее. Если контроль не предусмотрен, например используется служба IP без транспор-ого протокола TCP (раздел 9.4.9), то прикладная программа несет ответствен-jTb за проверку результата передачи. Эта операция сложнее, чем это кажется, ожно использовать сообщение, подтверждающее прием, но нет гарантии, что оно 40, в свою очередь, не будет потеряно и отправитель не начнет новую передачу. Эта Роблема не имеет общего решения - стратегии передачи сообщений должны в каж-°м случае рассматриваться индивидуально. Возможным решением является поме-Ть и нумеровать каждое сообщение таким образом, чтобы отправитель и получа-ь могли следить за порядком передачи. Этот метод используется в некоторых "Пах коммуникационных протоколов (раздел 9.4). 10.6. Методы программирования в реальном времени 10.6.1. Что такое программа реального времени? Программирование в реальном времени представляет собой раздел мультипро граммирования, который посвящен не только разработке взаимосвязанных парад лельных процессов, но и временным характеристикам системы, взаимодействующее с внешним миром. Между программами реального времени и обычными последовательными про граммами с четко определенными входом и выходом имеются существенные различия. Некоторые проблемы, возникающие при использовании строго последовательной программы для управления параллельными по природе процессами, были описаны в разделе 2.1. Ниже перечислены отличия программ реального времени от последовательных программ. • Логика исполнения программы определяется внешними событиями. • Программа работает не только с данными, но и с сигналами, поступающими из внешнего мира, например, от датчиков. • Логика развития программы может явно зависеть от времени. • Жесткие временные ограничения. Невозможность вычислить результат за определенное время может оказаться такой же ошибкой, как и неверный результат ("правильный ответ, полученный поздно, - это неверный ответ"). • Результат выполнения программы зависит от общего состояния системы, и его нельзя предсказать заранее. • Программа, как правило, работает в многозадачном режиме. Соответственно, необходимы процедуры синхронизации и обменаданными между процессами. • Исполнение программы не заканчивается по исчерпании входных данных - она всегда ждет поступления новых данных. Важность фактора времени не следует понимать как требование высокой скорости исполнения программы. Скорость исполнения программы реального времени должны быть достаточной для того, чтобы в рамках установленных ограничении ре агировать на входные данные и сигналы и вырабатывать соответствующие выходные величины. "Медленная" система реального времени может великолепно управлять медленным процессом. Поэтому скорость исполнения программ реального Р. необходимо рассматривать относительно управляемого процесса или необходи скорости. Типичные приложения автоматизации производственных процессов т . ------тгояяу - порядК ние функций операционной системы (вызовы ядра из прикладной программы, милуя стандартные средства). Помимо этого при программировании в реальном време-используются методика мультипрограммирования и модель "клиент-сервер", поскольку отдельный процесс или поток обычно выполняют только некоторую самостоятельную часть всей задачи. 10.6.2. Среда программирования Прежде чем переходить к вопросам собственно программирования в реальном времени, рассмотрим среду, в которой исполняются программы. Среда выполнения может варьироваться от мини-, персональных и одноплатных микрокомпьютеров и локальных шин, связанных с окружающей средой через аппаратные интерфейсы, до распределенных систем "клиент-сервер" с централизованными базами данных и доступом к системе высокопроизводительных графических рабочих станций. В комплексной системе управления промышленными и технологическими процессами может одновременно использоваться все перечисленное оборудование (раздел 9.6). Разнообразие аппаратной среды отражается и в программном обеспечении, которое включает в себя как программы, записанные в ПЗУ, так и комплексные операционные системы, обеспечивающие разработку и исполнение программ. В больших системах создание и исполнение программ осуществляются на одной и той же ЭВМ, а в некоторых случаях даже в одно время. Небольшие системы могут не иметь средств разработки, и программы для них должны создаваться на более мощных ЭВМ с последующей загрузкой в исполняющую систему. То же касается и микропрограмм, "зашитых" в ПЗУ оборудования производителем (firmware), - они разрабатываются на ЭВМ, отличной от той, на которой исполняются. Первой задачей программиста является ознакомление с программной средой и доступными инструментальными средствами. Проблемы, с которыми приходится сталкиваться, начинаются, например, с типа представления данных в аппаратуре и программах, поскольку в одних системах применяется прямой, а в других - инверсный порядок хранения бит или байт в слове (младшие байты хранятся по старшим адресам). Таких тонкостей очень много, и опытный программист знает, как отделить общую структуру данных и код от технических деталей реализации в конкретной аппаратной среде. Важно как можно раньше выяснить функции, обеспечиваемые имеющейся сре-°и. и возможные альтернативы. Например, микропроцессор Motorola 68000 имеет в скорости. Типичные приложения автоматизации производсиспп!..- - ядка буют гарантированное время ответа порядка IMC, no.ro.ue .и 0.1 мс. При программировании в Рнм времени о б ,ес- ,-ни „,p, сообщений. В UNIX и других операционных системах связь фективность и время реакции программ.Соответственно, разраоотк . - *flv ппп„о....... ..... *ет ос" команд инструкцию test and set, и поэтому связь между задачами мо-"0ДДепГ1™„ ! области памяти. Операционная система VAX/VMS но связана с параметрами операционной системы, а в распределенных си и локальной сети. Особенности программирования в реальном времени требуют специальной НИКИ и методов, не использующихся при последовательном программировании, торые относятся в основном к влиянию на исполнение программы внешней -Р {[, временных параметров. Наиболее важными из них являются перехват прерыва обработка иск.тючительных (нештатных) ситуаций и непосредственное использ стема " пр* процессами наиболее удобно осуществлять через каналы. При разработке , °1Рамм для среды UNIX следует стремиться, с одной стороны, максимально эф-тивно использовать ее особенности, например стандартную обработку входных и одных данных, а с другой - обеспечить переносимость (portability) между разны-" версиями UNIX. 8а того что многозадачные системы и системы реального времени разрабаты- "Тся коллективами программистов, необходимо с самого начала добиваться ясно-> Какие методы и приемы используются. [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31] [32] [33] [34] [35] [36] [37] [38] [39] [40] [41] [42] [43] [44] [45] [46] [47] [48] [49] [50] [51] [52] [53] [54] [55] [56] [57] [58] [59] [60] [61] [62] [63] [64] [65] [66] [67] [68] [69] [70] [ 71 ] [72] [73] [74] [75] [76] [77] [78] [79] [80] [81] [82] [83] [84] [85] [86] [87] [88] [89] [90] 0.0145 |