- •20 Билет
- •1)Установление связи
- •2) Передача данных
- •2.Системные вызовы
- •3.Примеры
- •2 Билет.
- •1.Управление процессами
- •2. Сигналы.
- •3 Билет
- •1.Обработка Сигнала
- •2) Группы процессов
- •3)Примеры
- •4 Билет
- •1)Посылка сигналов процессами
- •2)Межпроцессные комуникации
- •3)Примеры в качестве примера можно привести программу ,которая принимает сигналы о прерывании (sigint) и сама посылает их (в результате выполнения функции kill
- •5 Билет.
- •6 Билет.
- •7 Билет
- •1)Атомарные (неделимые) операции с каналами
- •2)Примечания к полудуплексным каналам
- •8 Билет
- •1)Именованные каналы (fifo: First In First Out): основные понятия
- •2)Операции с fifo
- •3) Примеры
- •9 Билет
- •1) Базовые понятия System V ipc
- •2) Идентификаторы ipc
- •10 Билет
- •11 Билет
- •1)Буфер сообщения
- •13 Билет
- •1)Системный вызов msgctl
- •2)Семафоры. Основные понятия
- •1)Системный вызов semget.
- •2) Системный вызов semop.
- •15 Билет
- •1) Системный вызов semctl
- •2) Разделяемая память. Основные понятия.
- •3) Примеры
- •16 Билет
- •1) Системный вызов shmget
- •2) Системный вызов shmctl
- •3) Примеры
- •17 Билет
- •Системный вызов shmat
- •Системный вызов shmdt
- •18 Билет
- •Системный вызов mmap
- •19 Билет
- •1) Создание сокета
- •2) Привязка к локальным именам
- •3) Примеры:
- •20 Билет
- •1)Установление связи
- •2) Передача данных
- •3) Примеры Установление связи
- •Передача данных
- •21 Билет
- •1. Закрытие сокетов.
- •22 Билет.
- •1) Алгоритмы
- •2) Оценки эффективности алгоритмов.
- •3) Примеры
- •23 Билет
- •1.Ядро операционной системы
- •2.Системные вызовы
- •3.Примеры
- •24 Билет.
- •25 Билет
- •1) Системный вызов semctl
- •2) Разделяемая память. Основные понятия.
- •3) Примеры
- •26 Билет
- •1) Группы процессов
- •2)Обработка Сигнала
- •3)Примеры
- •27 Билет
- •1) Создание сокета
- •2) Привязка к локальным именам
- •3) Примеры:
- •28 Билет.
- •29 Билет
- •1. Закрытие сокетов.
- •30 Билет
- •1)Установление связи
- •2) Передача данных
- •3) Примеры Установление связи
- •Передача данных
22 Билет.
1) Алгоритмы
Нередко в процессе написания программы, пусть даже системной, мы сталкиваемся с задачей оценки времени ее работы, а точнее времени работы самого алгоритма. С формального определения этого понятия мы и начнем изложение.
Алгоритм — это конечная последовательность инструкций, каждая из которых имеет четкий смысл и может быть выполнена с конечными вычислительными затратами и за конечное время.
2) Оценки эффективности алгоритмов.
Как правило, возникает необходимость анализировать конструируемый алгоритм. Такой анализ должен дать четкое представление, во-первых, о емкостной и, во-вторых, о временной сложности процесса.
Первая часть вполне ясна: речь идет о размерах памяти, в которой предстоит размещать все данные, участвующие в вычислительном процессе. Естественно, к ним относятся входные наборы, промежуточная и выходная информация. Возможно, не все перечисленные наборы требуют одновременного хранения, это значит, что удается сэкономить. В ряде случаев, впрочем, оценка емкостной сложности становится менее очевидной: так обстоит дело при использовании динамических структур, но об этом позже. А вот анализу временной трудоемкости мы уделим внимание здесь.
Итак, поставлена некоторая задача и для её решения спроектирован алгоритм, описывающий вычислительный процесс, который завершается за конечное число действий-шагов. Мы уже говорили, что реальное время выполнения каждого отдельного шага зависит от конкретного вычислительного устройства. Иначе говоря, неотъемлимым участником вычислительного процесса (не алгоритма!) является исполнитель. А вот имея в виду предполагаемого исполнителя, следует заранее оценить его вычислительные способности.
Можно сказать, что алгоритм должен быть понятен исполнителю. Это означает, что любое предписание алгоритма должно входить в тот фиксированный набор инструкций, которые исполнитель умеет реализовывать. Скажем, ваш карманный калькулятор рассчитан на выполнение нескольки арифметических операций, а более мощный, программируемый калькулятор, уже готоввыполнять несложные программы. Соответственно, наборы встроенных, элементарных, инструкций у этих устройствразличаются. При том, любая команда, которую готов выполнить второй калькулятор, все равно состоит из некоторого числа арифметических и логических операций, другое дело, что нам не приходится их вызывать по отдельности. Таким образом, либо алгоритм явно предписывает выполнять арифметико-логические операции, – и такой уровень программирования рассчитан непосредственно на работу процессора, – либо используются «укрупненные» инструкции, и для их обработкиприменяется специальный язык. Так, общение клиента с банкоматом предусматривает участие двух исполнителей алгоритма – человека и банкомата, – причем первый из них обращается ко второму посредством кнопочного интерфейса. Опытный владелец пластиковой карты знаком с процедурой, тем не менее, второй участник процесса не учитывает компетентность клиента, и потому на табло высвечиваются, поочередно, все необходимые инструкции. Как видим, разработчики системы, обеспечивающей этот диалог, довели пошаговую детализацию алгоритма до определенного уровня «компетентности», разбив укрупненные шаги – «снятия наличности» или «получения справки о счете» – на шаги более мелкие. Как мы выяснили, исполнитель нашего алгоритма должен «уметь» выполнить любую инструкцию из числа тех, которые он воспринимает как элементарные, а никакие другие он и не выполнит.
Собственно, одно из различий между процессорами компьютеров состоит в несовпадении их «личных» наборов инструкций. Но было бы нелепо в предлагаемом читателю курсе ориентироваться на столь «интеллектуально ограниченного» исполнителя, каким является обыкновенный процессор. Напротив, «способности» нашего подразумеваемого исполнителя должны постепенно развиваться. Потому, по мере удаления от начальных страниц, степень детализации будет уменьшаться, и алгоритмы будут описываться в укрупненных шагах. Так, опытный повар вполне готов исполнить предписание «приготовить ростбиф», – помните, мы с ним выше сталкивались? – как элементарную инструкцию. Предположим, алгоритм для решения некоторой задачи нам удалось построить. Раз так, чтомешает предположить существование и другого алгоритма, и еще следующего? Но если удается сконструировать целый ряд различных алгоритмов решения одной и той же задачи, то кажется разумным – выбрать «наилучший». Что под этим следует понимать? Как правило, речь идет о таком варианте решения, который, в сравнении с конкурентами, нуждается в наименее продолжительном по времени вычислительном процессе. Разумеется, давать такую оценку правомерно, лишь имея в виду одного и того же потенциального исполнителя. Далее: скорость реализации выбираемого алгоритма может существенно зависеть от содержания набора входных данных. Скажем, быстрый «в среднем» механизм способен давать сбои в отдельных «плохих» случаях. И, если задача должна наверняка решаться за определенное время работы процессора, то в этом случае, вероятно, мы предпочтем алгоритм более медленный в среднем, зато надежный в худших ситуациях. За примерами вновь обратимся к некомпьютерной сфере. Чтобы выпить чашку кофе, надо, во всяком случае, подогреть воду. Достаточно удобна и эффективна в этом случае кофеварка или мощный электрочайник. Если в ваш дом, что весьма вероятно, подведено электричество, то способ решения задачи при помощи одного из указанных приборов стоит предпочесть в большинстве случаев. Однако неполадки в распределительном электрощите, как бы редко они ни возникали, могут лишить вас ожидаемого удовольствия. Так что газовые плиты пока не стоит повсеместно заменять на электрические.
Впрочем, остается и самый надежный, хотя и наиболее трудоемкий метод: вскипятить воду на открытом огне, разложив небольшой костер. Чтобы читатель не забывал анализировать и емкостную сложность алгоритма, заметим, что последнее является примером сочетания наихудшей эффективности как по времени, так и по требованиям к ресурсам (учитывается безвозвратный расход горючего и низкий коэффициент полезного действия при изменении температуры воды). Однако даже такой алгоритм имеет право на существование!
Итак, давая оценку быстродействия алгоритма, следует рассмотреть поведение вычислительного процесса в среднем и отдельно в экстремальных условиях, т.е. в худшем случае.
Моделирование «худших» случаев всегда связано с содержанием самого алгоритма. Можно предложить лишь малое число рецептов выделения и рассмотрения подобных ситуаций. Один из них состоит в проверке поведения алгоритма на входных данных, принимающих граничные значения из разрешенного диапазона, другой в тестировании алгоритма на максимально больших по объему входных наборах, что важно для анализа как временной, так и емкостной эффективности.
Пожалуй, умение предвидеть «нехорошие» ситуации, - а они нередко возникают при выполнении готовой программы, - как раз и отличает квалифицированного алгоритмиста от обыкновенного кодировщика. В связи с расширением сферы производства программного обеспечения, сформировалась даже самостоятельная специализация - «тестеры программ».
Хорошей тренировкой в развитии навыков проектирования контрпримеров к разрабатываемому алгоритму и, разумеется, к программе станет для читателя выполнение заданий, построенных по современным «олимпиадным» канонам. Далее будут предложены многочисленные примеры, решение которых состоит в написании соответствующих программ.
Однако продолжим обсуждение того, как оценивать временную эффективность собственно алгоритма. Обычно ее не связывают с конкретной вычислительной установкой, а оперируют только «шагами». На самом деле, хорошо бы давать такие оценки, которые будут актуальны и в будущем, когда техническое (аппаратное) быстродействие наверняка возрастет.
Естественно, любой шаг алгоритма реализуется некоторым числом машинных операций, т.е. тех самых элементарных инструкций исполнителя, поскольку вряд ли вы станете проектировать алгоритм на языке ассемблера. По существу, анализ требует такой степени детализации алгоритма, чтобы в отношении отдельного шага не требовалась его дальнейшая алгоритмическая проработка. Здесь возможны лишь две ситуации: либо фиксированное время исполнения такого шага определено некоторым набором простых, без циклов, команд языка программирования; либо речь идет об «укрупненном» шаге, в отношении которого соответствующий анализ уже проводился и результаты известны.
