1. Введение в Unix. 1.1. Краткая характеристика ОС Unix.

advertisement
1. Введение в Unix.
1.1. Краткая характеристика ОС Unix.
Среди компьютерных операционных систем Unix занимает особое место. Обладая широкими возможностями,
свойственными для всех операционных систем и, прежде всего, для Windows, Unix является наиболее мощной и надежной системой
для реализации технологий построения телекоммуникационных сетей и удовлетворяет требованиям “Оранжевой книги” по защите
информации в компьютерных системах согласно классу С2. Официальной датой рождения ОС Unix принято считать 1 января 1970г, а
уже с начала 80-х годов сеть компьютерных сетей Интернет стала частью Unix благодаря уникальным сетевым возможностям
последней. С 1995 года университеты и колледжи США на 80% своих компьютеров используют операционные системы Unix.
Unix удовлетворяет всем требованиям, предъявляемым к современным операционным системам, включая следующие:
















Поддержка всех основных сетевых протоколов.
Поддержка всех основных файловых систем.
Квотирование дискового пространства.
Удобный пользовательский и программный интерфейсы.
Возможность эффективного управления ресурсами компьютера.
Многозадачный режим.
Многооконный графический интерфейс.
Многоязыковая поддержка для шрифтов и клавиатур.
Многопроцессорность.
Наличие механизмов работы с виртуальной памятью.
Эмуляция математического сопроцессора.
Обеспечение защиты информации от несанкционированного доступа, а также защита от неправильных действий
пользователя.
Разделяемые библиотеки.
Виртуальные консоли.
Переносимость ОС благодаря тому, что программы ОС написаны на языке высокого уровня Си.
Многоплатформенность, т.к. ОС Unix практически не привязаны к архитектуре систем, для сравнения, ОС Windows 98
ориентирована только на архитектуру Intel.
Среди всех требований, которым удовлетворяют ОС семейства Unix, нас будут интересовать их возможности при реализации
компьютерных сетей. Сегодня все ОС работают в Интернете и достаточно хорошо. Однако ОС Unix позволяет получить скорость
работы в Интернете в несколько раз больше, чем другие ОС.
Еще одним достоинством Unix является значительно более высокая надежность связи, что позволяет копировать из Интернета большие
объемы информации.
Unix позволяет организовать полноценный доступ к Интернету с каждого компьютера локальной сети через один зарегистрированный
компьютер. Регистрация остальных компьютеров не требуется.
Unix обладает более высокой, чем другие ОС, степенью защиты информации от проникновения в компьютер через Интернет и при
работе в локальной сети.
Степень защиты от вирусных атак в Unix оказывается также выше.
Работа программных средств в Unix отличается надежностью и стабильностью.
Unix позволяет создавать надежные архивы информации, Web-Серверы, серверы баз данных с удаленным доступом,
серверы локальных компьютерных сетей, мощные Интернет-станции с полным набором возможностей Интернет – провайдера.
Инсталляционные пакеты многих версий Unix разрешены для бесплатного копирования через Интернет.
ОС Unix имеют стандартный набор средств, корректное использование которых позволяет строить защищенные
компьютерные сети. Механизмы обеспечения безопасности соответствуют классу С2 «Оранжевой книги» и присутствуют в Unix с 1992
г. (Unix SVR4). Стандартные средства защиты в Unix имеют следующие возможности:

Защита через пароли. Любой пользователь в Unix имеет свое имя и свой пароль, без которых он не может логически
включиться в систему.

Защита файлов. Даже если пользователь вошел в систему, не обладая сответствующими правами доступа к файлам, он не
может работать с чужими файлами. В Unix существует один, так называемый, суперпользователь (superuser), который входит
в систему с именем root и имеет свой пароль, этот пользователь имеет неограниченные права доступа к файлам и является
администратором системы.

Возможность изменения статуса пользователя с использованием команды su (superuser), если только ему известен пароль
суперпользователя, или команды newgrp, позволяющей изменить группу, к которой принадлежит пользователь.

Шифрование файлов с помощью программы crypt, которая предусматривает использование системы ключей.

На основе использования стандартных средств защиты система является безопасной в такой степени, в какой она настроена
суперпользователем. Вместе с тем защита на сетевом уровне требует использования дополнительных средств, прежде всего
системы сетевой аутентификации и межсетевых экранов.
1.2. Общие сведения о сетевых возможностях Unix.
Unix развивалась одновременно с компьютерными сетями с конца 60-х годов.
Работа по созданию сетей началась с проекта ARPA в интересах Министерства Обороны США. Ее целью было развитие
информационной сети, предназначенной для руководства войсками, способной противостоять ядерным ударам. Сеть должна была
удовлетворять двум основным требованиям:
- отсутствие центрального узла связи, выход из строя которого мог бы парализовать всю сеть;
- функционирование даже в том случае, если значительная часть сети разрушена.
В 1969 г. возникла сеть ARPANET, явившаяся предшественником Интернета. В 70-ых годах было разработано семейство
протоколов TCP/IP и протокол UUCP (Unix to Unix Copy), который позволил передавать файлы с помощью последовательного
интерфейса, запускать программы на другой Unix-машине, выполнять вход в ОС на другом компьютере, посылать и принимать
почтовые сообщения. UUCP может использоваться в сетях любого класса - как локальных, так и глобальных.
Важным этапом для развития сетей явился 1980 год, когда фирма Bolt, Beranek and Newman (BBN) подписала контракт с
Министерством Обороны США на разработку средств поддержки семейства протоколов TCP/IP в ОС Unix BSD. Версия Unix BSD
была выпущена в середине 1983 года. Она поддерживала работу в локальных сетях Ethernet, что способствовало широкому
распространению этой технологии, а также позволяла подключаться к сети ARPANET.
С 1985 года семейство протоколов TCP/IP на основе ОС BSD Unix становится стандартом для построения гетерогенных
сетей, обеспечивающих следующие возможности:
- выполнение процедур и команд на удаленном компьютере;
- поддержка распределенной файловой системы NFS, позволяющей осуществить доступ к ресурсам удаленного компьютера;
- вход в систему для диалоговой работы на удаленном компьютере;
- передача файлов с одного компьютера на другой;
- поддержка электронной почты;
- поддержка информационно-поисковой системы в форме меню и в форме гипертекста;
- поддержка работы в файловых текстах распределенных файловых систем в рамках всего мира;
-поддержка системы банков данных.
1.3. Архитектура Unix.
При самом общем взгляде архитектуру ОС Unix можно представить в виде двухуровневой модели.
Первый уровень образует ядро операционной системы (kernel). Ядро взаимодействует с аппаратной частью компьютера, изолируя
прикладные программы от особенностей построения машины. Ядро предоставляет прикладным программам набор услуг, к которым
относятся:
- операции ввода–вывода (открытия, чтения, записи и управления файлами);
- операции создания и управления процессами, их синхронизации и межпроцессное взаимодействие.
Все приложения запрашивают услуги ядра посредством системных вызовов.
Второй уровень составляют приложения или задачи, к числу которых относятся:
- системные, определяющие набор функций системы;
- прикладные, обеспечивающие пользовательский интерфейс.
Ядро не выполняет ни одной функции, непосредственно служащей пользователю. Для этой цели служат многочисленные утилиты
второго уровня, выступающие посредником между пользователем и ядром.
1.4. Ядро операционной системы.
Ядро обеспечивает функционирование всех элементов операционной системы. Ядро содержит системные программы,
выполняющие диспетчерские функции. Оно создает процессы в системе и управляет ими, распределяет память, обеспечивает доступ к
файлам и периферийным устройствам.
Ядро состоит из трех основных подсистем:
- управления файлами;
- управления процессами;
- ввода/вывода.
Взаимодействие прикладных программ пользователя с ядром происходит
при помощи системных вызовов. Когда пользователь запускает программу на исполнение, операционная система создает процесс,
который посредством системного вызова запрашивает на выполнение определенную процедуру ядра. Ядро выполняет эту процедуру и
возвращает процессу необходимые данные.
Подсистема управления файлами обеспечивает унифицированный доступ к данным, расположенным на дисковых
накопителях, и периферийным устройствам. С этой целью используются системные вызовы: open, read, write. Также данная подсистема
контролирует права доступа к файлу, выполняет операции размещения, удаления, записи и чтения файла, обеспечивает
перенаправление запросов, адресованных периферийным устройствам - соответствующим модулям подсистемы ввода/ вывода.
Подсистема управления процессами обеспечивает:
- создание и удаление процессов;
- распределение системных ресурсов между процессами (память, вычислительные ресурсы);
- межпроцессное взаимодействие.
Для решения этих задач подсистема имеет
взаимодействия.
планировщик процессов, модуль управления памятью и
модуль межпроцессного
Запущенная программа порождает ряд процессов, которые образуют иерархические отношения между собой. Подсистема управления
процессами контролирует их выполнение. В Unix существуют понятия родительского и дочернего процессов. Один процесс может
порождать другие процессы, их отношения можно представить в виде генеалогического дерева родственных отношений. Общим
прародителем всех процессов в ОС является процесс init. Другие процессы порождаются с помощью системного вызова fork.
Подсистема ввода-вывода выполняет запросы подсистем управления файлами и процессами для доступа к периферийным устройствам
(дискам, терминалам и т.д.). Подсистема ввода-вывода обеспечивает буферизацию данных и взаимодействие с драйверами устройств –
специальными модулями ядра, непосредственно обслуживающими внешние устройства.
1.5. Пользователи операционной системы.
В ОС Unix существует две категории пользователей: суперпользователь и обычные пользователи.
Суперпользователь или системный администратор имеет имя root и обладает правом доступа ко всем файлам и каталогам,
отвечая за устойчивую работу системы и ее безопасность. Суперпользователь регистрирует остальных пользователей, организует их
работу и обеспечивает взаимодействие всех компьютеров в сети. При входе в ОС суперпользователь вводит свое имя root и личный
пароль, установленный при инсталляции ОС.
Каждый пользователь имеет в системе свое имя и пароль. Если при входе в ОС имя и пароль введены правильно, то машина
выдает приглашение пользователю для начала работы. Приглашение имеет вид определенного символа, например, знак $, его можно
установить по желанию пользователя. Система различает пользователей не по имени, а по соответствующему идентификатору
пользователя UID. Права пользователя в системе ограничены, например, он не может зарегистрировать нового пользователя, не имеет
доступа к файлам другого пользователя, если суперпользователь не предоставит ему такие права.
В Unix существуют также группы пользователей. Группа имеет уникальное имя и соответствующий имени групповой
идентификатор GID.
Вся информация о пользователях хранится в файле /etc/passwd. Это текстовый файл, право на чтение которого имеют все пользователи,
а право на запись имеет только суперпользователь. Пароли пользователей хранятся в файле /etc/shadow в зашифрованном виде,
закрытом для чтения и записи. Информация о группах хранится в файле /etc/group.
С точки зрения системы, пользователь - не обязательно человек. В Unix имеются стандартные пользователи, реализуемые программно,
их называют псевдопользователями и к ним относятся:
- adm - владелец файлов системы ведения журналов;
- cron - владелец файлов запуска программ по расписанию;
- lp - владелец файлов печати;
- bin - владелец всех исполняемых файлов.
1.6. Сеанс работы в Unix.
Сеанс работы (рабочая сессия) персонального пользователя на ЭВМ начинается со входа в систему и заканчивается
командой выхода из нее - exit. В процессе работы пользователь может запускать прикладные программы и утилиты, право на запуск
которых он имеет. При работе за терминалом допускается использование нескольких виртуальных консолей, переключение на которые
осуществляется нажатием клавиши Аlt и одной из функциональных клавиш F1, F2, F3 и т.д. С каждой консоли можно открыть и вести
отдельный сеанс работы.
С точки зрения пользователя в ОС Unix существует два типа объектов: файлы и процессы. Все данные ОС хранятся в виде
файлов, одним из файлов, например, является ядро ОС. Файлы ОС объединены по определенным признакам в каталоги. Когда
пользователь запускает программу, ядро загружает исполняемый файл, создает соответствующий файлу процесс и передает ему
управление. Во время выполнения процесс может считывать или записывать данные в файл.
Работа в операционной системе осуществляется путем использования текстового или графического интерфейса. Интерфейс –
это средство для взаимодействия ОС с пользователем. Работа в текстовом режиме предполагает ввод команд из командной строки
после приглашения. Команды вводятся с помощью клавиш. Графический интерфейс обеспечивает система X Window. Основным
устройством ввода в графическом режиме является манипулятор «мышь», аналогично тому, как это делается в системе Windows.
Работа пользователя в ОС осуществляется с помощью командного интепретатора, который в архитектуре ОС является
внешней оболочкой по отношению к ядру. Оболочка – это программа, которая упрощает взаимодействие пользователей с ядром ОС,
являясь посредником между ними, а также помогает выполнять другие программы. Функции операционной системы сосредоточены в
ядре, образующем программную часть ОС. Оболочка воспринимает команды, вводимые пользователем, проверяет их правильность и
организует запросы ядру. В Unix имеется несколько оболочек.
Любая команда, являющаяся отдельной программой, не встроенной в оболочку, будет выполняться одинаково, независимо от
оболочки. Например, команда печати lp работает всегда одинаково. Некоторые команды встроены в оболочку, их действие может
изменяться при смене оболочек. Если команды встроены в оболочку, они запускаются несколько быстрее.
Первой программой, с которой начинается работа пользователя, является программа командного интерпретатора (оболочки),
имеющая имя shell.
1.7. Процессы в ОС Unix.
1.7.1. Общие сведения о процессах.
Программа в Unix представляет собой исполняемый файл. Для того чтобы программа могла быть запущена на выполнение,
операционная система должна создать среду выполнения программы. Эта среда включает ресурсы памяти, возможность доступа к
устройствам ввода – вывода и различные системные ресурсы. Среда выполнения с набором выполняемых инструкций получила
название процесса. Когда пользователь запускает программу на исполнение, операционная система создает процесс, то есть процесс
можно также представить как программу в стадии ее выполнения. Однако, нельзя отождествлять программу и процесс. Одна
программа в простейшем случае может быть представлена одним процессом, например, программа выполнения команды who.
Сложные задачи, например, программы печати, порождают в системе несколько выполняемых процессов. Управление процессами со
стороны ОС заключается в распределении ресурсов системы. Одновременное выполнение нескольких процессов может быть реальным,
если они обрабатываются разными процессорами многопроцессорной ЭВМ и виртуальным, когда процессор время от времени
переключается с исполнения одного процесса на исполнение другого. Ранее отмечалось, что процессы образуют иерархические
отношения между собой. Если один процесс порождает другие процессы, он называется родительским. Процесс, который наследует
свойства родительского процесса, включая среду выполнения, рабочую директорию, открытые файлы, называется дочерним. Общий
прародитель всех процессов – процесс init. Любой другой процесс в ОС порождается с помощью системного вызова fork.
Каждому созданному процессу ОС назначает уникальный идентификатор PID, который идентифицирует процесс и для самой ОС, и для
всех команд и системных вызовов. Каждый процесс имеет также идентификатор родительского процесса PPID. Операционная система
управляет процессами, используя идентификаторы PID и PPID. Каждый новый запущенный процесс получает идентификатор на
единицу больший, чем имел предыдущий процесс. Увидеть идентификаторы PID и PPID запущенных процессов можно по команде:
$ ps –u
для ОС BSD
Если идентификатор достиг максимального для ОС значения, следующий процесс получает минимальный свободный PID и цикл
повторяется. Когда процесс завершает свою работу, ядро освобождает занятый им идентификатор.
Выполнение процесса заключается в точном следовании набору инструкций, который никогда не передает управление набору
инструкций другого процесса.
В соответствии с концепцией процесса он имеет процедурный сегмент, сегмент данных и свое собственное адресное пространство.
Процессы имеют возможность обмениваться друг с другом данными с помощью средств межпроцессорного взаимодействия, таких как
сигналы, семафоры, очереди сообщений, программные каналы, разделяемая память, общие файлы.
1.7.2. Типы процессов.
Системные процессы ориентированы на выполнение системных функций. Они являются частью ядра, всегда расположены в
оперативной памяти, не имеют соответствующих им программ в виде исполняемых файлов и запускаются при инициализации ядра
системы. К системным процессам относится процесс init, являющийся прародителем всех остальных процессов. Выполняемые
инструкции и данные этих процессов находятся в ядре и недоступны для других процессов.
Пользовательские процессы порождаются во время сеанса работы пользователя. Важнейшим пользовательским процессом
является командный интерпретатор. Он обеспечивает работу пользователя и запускается сразу после регистрации пользователя в
системе. При выходе из системы все пользовательские процессы будут остановлены.
Некоторые процессы не связаны ни с каким управляющим терминалом. Они называются демонами. Демоны отличаются от других
процессов тем, что выполняют специфические функции, например, администрирование в сетях. Демоны не могут управляться
пользователем. Они ожидают пока тот или иной процесс запросит определенную услугу, например, демон ждет, пока наступит
заданное время и выдает определенное задание.
1.7.3. Атрибуты процесса.
Каждый процесс в ОС Unix характеризуется набором признаков – атрибутов, отличающих его от других процессов.
Большинство атрибутов процесс наследует от родительского процесса, одна часть атрибутов устанавливается ОС, другая часть
порождается самим процессом в ходе его выполнения. Некоторые атрибуты были рассмотрены ранее, к ним относятся идентификатор
(номер) процесса PID (Process Identifier) и идентификатор родительского процесса PPID (Parent Process ID), которые назначает ОС.
К атрибутам также относятся:
1. Контролирующий управляющий терминал. Открывается процессом для чтения и записи. С его помощью процессу могут
быть посланы сигналы прерывания. Управляющим терминалом является тот, на котором запущен командный интерпретатор
(программа, связывающая пользователя с ОС). Управляющий терминал устанавливается только для тех процессов, которые запущены
программой пользователя. Процессы–демоны не связаны ни с каким управляющим терминалом. Не имеют управляющего терминала
также процессы, запущенные самими демонами. Команда ps выводит название управляющего терминала в столбце tty.
2.Реальный и эффективный идентификаторы пользователя и группы.
Каждый пользователь, зарегистрированный в ОС, имеет идентификаторы пользователя UID и группы GID, которые хранятся в файлах
/etc/passwd и /etc/group. Для каждого пользователя ОС устанавливает определенные права доступа к файлам (код защиты файла).
Каждому файлу могут быть установлены дополнительные атрибуты SUID и SGID. Эти атрибуты изменяют права пользователя в
сторону расширения. Обычно, запускаемая программа получает права доступа к системным ресурсам на основе прав доступа
пользователя, запустившего программу. Установка атрибутов SUID и SGID изменяет это правило. Если для файла установлены
атрибуты SUID и SGID, то ОС назначает права доступа к файлу, исходя из прав доступа владельца файла и владельца группы.
Например, запущенный исполняемый файл, которым владеет суперпользователь, получает неограниченные права доступа к
системным ресурсам независимо от того, кто его запустил. При этом установка SUID приведет к наследованию прав владельца файла, а
установка SGID – владельца группы.
Каждый процесс в Unix кроме идентификаторов PID и PPID имеет четыре пользовательских идентификатора UID, GID,
EUID и EGID. UID и GID определяют реального владельца процесса, а EUID и EGID определяют права доступа процесса к файлам. Эти
идентификаторы называют эффективными. Обычно реальный и соответствующий ему эффективный идентификатор одинаковы, в этом
случае процесс имеет те же права, что и пользователь, запустивший его. Однако существует возможность задать процессу более
широкие права, чем права пользователя, запустившего процесс. Это достигается установкой атрибутов файла SUID и SGID. Тогда
эффективному идентификатору процесса присваивается значение идентификатора владельца исполняемого файла, например,
суперпользователя.
Таким образом, реальные и эффективные идентификаторы процесса всегда совпадают, но если для исполняемого файла
установлены атрибуты SUID и SGID, то после его загрузки реальные идентификаторы процесса изменяются на идентификаторы
владельца или группы исполняемого файла, то есть становятся эффективными.
Рассмотрим пример действия реальных и эффективных идентификаторов. Пусть имеются три файла первой группы владельцев с
именами file1, file2, file3 и три исполняемых файла prog1, prog2, prog3 второй группы владельцев, которые могут совершать действия
над файлами первой группы. Все файлы обоих групп имеют одного владельца. Требуется, чтобы другие процессы могли совершать
действия над файлами первой группы только при помощи программ второй группы.
Для достижения этой цели в коде защиты файлов второй группы должна быть разрешена смена идентификатора
пользователя для процесса, вызвавшего один из этих файлов. Тогда любой процесс, пожелавший работать с одним из файлов первой
группы, должен вызвать программу второй группы. Сделать это можно путем установки атрибутов SUID и SGID для файлов группы.
Идентификаторы сессии. Все процессы, которые пользователь запускает во время сеанса работы в Unix, объединяются в
сессию. Каждая сессия имеет процесс, который называют лидером сессии. Лидером сессии является самый старший процесс, который
имеет связь с терминалом пользователя, обычно это оболочка (командный идентификатор). Каждая сессия имеет свой номер
(идентификатор сессии) SID, с помощью которого ОС может управлять сразу всеми процессами пользователя, запущенными во время
сессии. Сессия работы пользователя заканчивается после завершения работы лидера сессии. Каждый пользователь может
одновременно вести несколько сессий с разных терминалов. Идентификатор сессии SID устанавливается равным PID ее лидера. Этот
параметр наследуется всеми пользовательскими процессами данной сессии.
Идентификаторы группы процессов. Процессы, выполняющие одно задание, внутри сессии логически объединяются в группы
процессов. Например, все процессы конвейера команд объединяются в одну группу. В каждый группе есть процесс-лидер группы.
Пользователь и ОС могут управлять сразу всеми процессами группы, не затрагивая процессы других групп в этой сессии. Лидером
группы является первая команда конвейера, для группы процессов устанавливается идентификатор PGID равный PID лидера группы.
1.7.4. Жизненный путь процесса.
Любой процесс в Unix создается системным вызовом fork. Процесс, сделавший вызов fork называется родительским, а вновь созданный
процесс – дочерним. Новый процесс является точной копией породившего его процесса, он имеет те же выполняемые инструкции и
данные и отличается только идентификатором PID. Для запуска новой программы процесс должен выполнить системный вызов exec.
При этом новый процесс не порождается, а создается адресное пространство, загружаемое содержимым новой программы, после
выполнения которой, созданный процесс прекращает свой жизненный путь.
Проследим действие процессов с момента загрузки ОС. После загрузки ядра операционной системы запускается процесс init. Процесс
init порождает процесс getty, с помощью которого осуществляется связь с терминалами ЭВМ. Процесс getty выводит на терминал
приглашение операционной системы и вызывает вместо себя программу login, которая осуществляет ввод регистрационного имени и
пароля пользователя. Если введенные пользователем данные соответствуют информации, содержащейся в регистрационных файлах
/etc/passwd и /etc/shadow, программа login завершает свою работу, вызывая вместо себя командную оболочку (интерпретатор shell), с
которой пользователь и работает в дальнейшем. Для выполнения команд пользователя оболочка порождает новые процессы. Допустим
пользователь, работая с командным интерпретатором shell, запускает команду ls. Текущий процесс shell делает системный вызов fork,
который порождает дочерний процесс shellНовый порожденный процесс shell делает системный вызов exec, указывая в качестве
параметра имя исполняемого файла ls, которое нужно загрузить в память вместо имени shell. Код программы ls замещает код
интерпретатора shell и программа ls начинает выполняться. После завершения работы программы ls созданный процесс прекращает
свой жизненный путь и его снова замещает процесс shell.
1.7.5.Средства межпроцессорного взаимодействия.
Средства межпроцессорного взаимодействия - IPC (Inter Process Communication) является базой для построения моделей
“клиент - сервер”, а технология построения моделей “клиент - сервер” образует основу для реализации сетей. При построении моделей
“клиент - сервер” в Unix используются следующие средства: сигналы, семафоры, программные каналы, очереди сообщений,
разделяемая память, а также специальные команды (write, cu, mail) и средства межмашинного взаимодействия, включающие различные
типы протоколов и файловых систем (uucp, tcp/ip, nfc, rfs).
Рассмотрим сначала только средства межпроцессорного взаимодействия: сигналы, семафоры, каналы, очереди сообщений и
разделяемую память.
Взаимодействие процессов необходимо для решения следующих задач:

Передача данных от одного процесса к другому, объем которых может варьироваться от нескольких десятков байт до
нескольких мегабайт.

Совместное использование данных. Вместо копирования информации от одного процесса к другому, процессы могут
совместно использовать один набор данных. Количество взаимодействующих процессов может быть больше двух.

Извещение одного процесса другим процессом о наступлении некоторого события. Это может понадобиться для
синхронизации выполнение нескольких процессов.
1.7.6. Сигналы.
Сигналы служат для передачи информации о возникновении определенного события от одного процесса к другому.
Например, для того чтобы остановить выполнение какого-либо процесса, ему необходимо послать сигнал завершения процесса.
Сигналы могут передаваться от одного процесса к другому или от ядра ОС к процессу. Инициировать появление сигнала может также
пользователь, например, при нажатии клавиш прерывания <DEL> или <CTRL>+<C> текущему процессу посылается сигнал SIGINT
(закончить процесс). Если в ходе процесса производится деление на ноль, ядро посылает ему сигнал SIGFPE (закончить процесс).
Для удобства использования каждый сигнал имеет символическую форму записи и цифровой код, которые хранятся в файле
signal.h. Список символических имен сигналов можно получить по команде:
$ kill –l
Этот список представлен в таблице:
№ Имя сигнала
Содержание
1
SIGHUP
Вырабатывается при отключении связи с терминалом.
Посылается всем процессам TGID.
2
SIGINT
При нажатии клавиши прерывания.
Посылается всем процессам TGID.
3
SIGQUIT
При нажатии клавиши QUIT.
Посылается всем процессам.
4
SIGILL
Вырабатывается
при
возникновении
аппаратных
неконтролируемых состояний. Посылается текущему PID
5
SIGTRAP
Вырабатывается при трассировке.
Посылается текущему PID.
6
SIGIOT
Вырабатывается при неисправностях в аппаратуре.
Посылается текущему PID.
7
SIGBUS
При ошибке в косвенной адресации.
Посылается текущему PID.
8
SIGFPI
При обработке чисел с плавающей точкой.
Текущему PID.
9
SIGKILL
10
SIGUSR1
11
SIGSEGV
12
SIGUSR2
13
SIGPIPE
14
SIGALRM
15
SIGTERM
17
SIGSHLD
18
19
20
21
SIGCONT
SIGSTOP
SIGTSTP
SIGTTIN
22
SIGTTOU
23
24
SIGURG
SIGXCPU
25
26
27
28
SIGXFSZ
SIGVTALRM
SIGPROF
SIGWINCH
29
30
SIGIO
SIGPWR
31
SIGSYS
При выдаче системного вызова KILL.
Адресуемому PID.
При системном вызове KILL.
Адресуемому PID.
При выходе за пределы сегмента.
Текущему PID.
При системном вызове KILL.
Адресуемому PID.
При записи в канал, когда нет читающего процесса.
Текущему PID. Записи в канал.
При окончании временной установки.
Посылается к PID установки.
При выполнении команды KILL в командном режиме.
Посылается адресуемому PID.
Когда заканчивается родительский процесс.
Родительскому процессу.
Продолжение процесса.
При остановке процессов при нажатии клавиш ctrl+z
При попытке фоновых процессов осуществить
управляющему терминалу. Фоновым процессам.
При попытке фоновых процессов осуществить
управляющему терминалу. Фоновым процессам.
доступ
к
доступ
к
При превышении процессорной квоты времени
Для данного процесса.
При превышении квоты дискового пространства.
При изменении размера окна в системе
X – Window
При уменьшении напряжения сети.
В зависимости от реализации.
При неверном системном вызове.
Текущему PID.
Для завершения процесса или посылки ему сигнала пользователя применяется команда:
$ kill [sig] PID…
где: sig – номер или символическое имя сигнала;
PID – идентификатор процесса, которому посылается сигнал.
Удалить можно только процесс (программу), на который пользователь имеет соответствующие права. Пример записи команды на
удаление процесса 1961 по сигналу SIGINT (номер 2) имеет вид:
$ kill 2 1961
Если сигнал не действует, можно послать более “строгий” сигнал SIGKILL(9):
$ kill 9 1961
Если идентификатор процесса PID, которому необходимо послать сигнал, неизвестен, его можно определить по команде ps. Например:
$ ps
PID
TTY
TIME
CMD
1421
tty1
00:00:00
login
1432
tty1
00:00:00
bash
1459
tty1
00:00:00
ps
Первый столбец показывает идентификатор процесса PID, второй – имя терминала, третий (TIME) – сообщает, сколько времени
выполнялась программа до ввода команда ps, последний столбец (CMD) показывает команду.
Команда ps без опций не показывает “старые” процессы, которые выполнялись в прошлом. Для просмотра “старых” процессов с
командной ps используется опция –е. Для того, чтобы узнать, какие процессы необходимо удалить, используется опция –l (от long длинный).
$ ps –l
F S
100 S
100 S
100 R
где:
F
S
UID
PID
PPID
C
PRI
UID PID PPID C PRI Ni ADDR
0 716 1
0 61 0
0 717 716 0 75 0
0 743 717 0 78 0
-
SZ WCHAN TTY TIME CMD
516 waity tty1 00:00:00 login
427 waity tty1 00:00:00 bash
631
tty1 00:00:00 ps
- флаг процесса, показывает в каком состоянии находится процесс;
- состояние процесса;
- идентификатор владельца процесса (программы);
- идентификатор процесса;
- идентификатор родительского процесса;
- время процесса;
- приоритет процесса;
Ni
- значение, характеризующее приоритет;
ADDR - адрес памяти, куда помещен процесс;
SZ
- виртуальная величина процесса (кбайт)
WCHAN – номер события, которого ждет процесс, если колонка пуста - это означает, что процесс выполняется.
Эта команда во втором столбце показывает состояние процесса. Рекомендуется удалять все процессы с состоянием Z (от Zombie).
Опция –l не сообщает имени владельца программы. Для включения в листинг, выводимый по команде ps, имени владельца необходимо
использовать опцию –f. В системе BSD вместо опций –fe используются опции –ax.
Средством посылки сигналов в ОС Unix является системный вызов kill. Средством восприятия сигналов служит системный вызов
signal. Системный вызов kill посылает выбранному процессу сигнал с определенным номером. Системный вызов signal воспринимает и
идентифицирует сигнал.
Действие сигналов проследим на следующем примере. Запустим в фоновом режиме команду vi (вызов экранного редактора):
$ vi&
[1] 2517
убедимся в том, что команда выполнена:
$ ps
получим ответ:
PID
TTY
TIME
CMD
2470
pts/0
00:00:00
bash
2517
pts/0
00:00:00
vi
2518
pts/0
00:00:00
ps
[1]+ stopped
Из ответа машины видно, что среди запущенных процессов имеется процесс с идентификатором 2517, соответствующий редактору vi.
Удалим процесс с идентификатором 2517:
$ kill -9 2517
[1]+ killed
Убедимся в том, что процесс 2517 удален:
$ ps
PID
TTY
TIME
CMD
2470
pts/0
00:00:00 bash
2519
pts/0
00:00:00 ps
Действительно, процесса 2517 нет, команда kill сработала.
Аналогично можно удалить процесс 2470, поддерживающий работу командного интерпретатора bash:
$ kill -9 2470
В результате произойдет выход на начало сеанса работы.
К генерации сигналов могут привести следующие события:
Ядро отправляет процессу (или группе процессов) сигнал при нажатии пользователем определенных клавиш или их комбинаций,
например, <DEL> или <CTRL>+<C>
Особые ситуации при выполнении процессов, например, деление на 0 или обращение к недопустимой области памяти. Обычно эти
ситуации определяются аппаратно, и ядру посылается прерывание. Ядро реагирует на прерывание отправкой соответствующего
сигнала процессу, находящемуся в стадии выполнения.
Определенные программные состояния системы. Например, при срабатывании таймера формируется сигнал SIGALRM.
При получении сигнала процесс имеет три варианта действий:
Системный вызов signal может проигнорировать сигнал. Нельзя игнорировать сигналы, посылаемые при делении на 0 и сигналы при
ссылках на недопустимые области памяти, так как дальнейшие действие ОС непредсказуемы;
Действие по умолчанию - сводится к завершению выполнения процесса;
Процесс может перехватить сигнал и самостоятельно обработать его. Сигналы SIGKILL и SIGSTOP нельзя ни перехватить, ни
проигнорировать.
Сигналы могут использоваться не только для завершения процессов, но и иметь специальное назначение для приложений. Например,
отправление сигнала SIGHUP серверу доменных имен DNS вызовет считывание базы данных с диска (для поиска соответствия
доменного имени и IP - адреса).
1.7.7. Семафоры.
Назначение рассматриваемого объекта межпроцессорного взаимодействия (IPC) соответствует его названию: семафоры
используются для синхронизации доступа к разделяемым (критическим) ресурсам. Под критическими ресурсами понимаются данные,
которые используются разными процессами, например, данные некоторого файла, необходимые для выполнения разных программ. К
критическому ресурсу в данный момент времени может иметь доступ только один процесс, для других процессов доступ должен быть
закрыт. Синхронизацию доступа разных процессов к критическим ресурсам по определенной схеме осуществляют семафоры. Процесс
может сам создать семафор, включить его в состояние запрета (0) и захватить ресурс. По истечении определенного интервала времени
процесс освобождает ресурс для других процессов и выключает семафор, что соответствует его разрешающему состоянию (1).
В простейшем случае роль семафора может выполнять триггер. Допустим, имеется некоторый файл (критический ресурс).
Когда некоторый процесс производит операцию над ресурсом, например, записывает данные в файл, доступ для других процессов к
этому файлу должен быть закрыт. Для этого свяжем с данным файлом триггер.
Перед началом работы с файлом процесс должен проверить состояние триггера, если он в нулевом состоянии (состояние
запрета), процесс идет, если триггер в единичном состоянии (состояние разрешения), процесс записывает данные в файл, но на время
записи триггер устанавливает в состояние 0 (запрет). После выполнения операции записи триггер нужно перевести в единичное
состояние (разрешения).
Для нормальной работы семафор должен быть доступен разным процессам, для этого доступ к нему должен быть
организован через ядро. Ядро обеспечит доступ к семафору в данный момент времени только одному процессу, иначе возможна
ситуация, когда при работе с критическим ресурсом одного процесса другой процесс изменит состояние семафора и нарушит
синхронизацию.
В более сложном случае семафор представляет собой не триггер, а многоразрядный счетчик или группу счетчиков,
объединенных общей управляющей структурой, например, дескриптором, правами доступа и т.д. Состояние счетчика характеризуется
любым положительным числом, а не только значениями 0 и 1.
Управляется семафор с помощью системных вызовов semget, semctl, semop, которые поддерживает ядро
Системный вызов semget создает семафор или обеспечивает доступ к нему, если семафор существует. По системному
вызову semctl проверяется состояние семафора и его настройка. Системный вызов semop переустанавливает текущее состояние
семафора. Состояние каждого семафора определяется его структурой данных semid, которую поддерживает ядро и которая включает
следующие поля:
struct ipc-perm sem-perm описание прав доступа
struct sem *sem-base
указатель на первый элемент массива семафоров
ushort sem-nsems
число семафоров в группе
time-t sem-otime
время последней операции
time-t sem-ctime
время последнего изменения
Кроме того, для каждого семафора имеется внутренняя структура данных sem, которая содержит следующие данные:
ushort semval
значение семафора
pid-t sempid
идентификатор процесса, выполнившую последнюю операцию над светофором;
ushort semncnt
число процессов, ожидающих увеличения значения семафора
ushort semzcnt
число процессов, ожидающих обнуления семафора.
Эта информация позволяет ядру производить операции над семафором, приводящие к выполнению трех действий:

Освободить ресурс.

Ждать.

Захватить ресурс.

Работу семафора можно проследить от момента получения системного вызова semget, в случае успешного завершения которого для
семафора устанавливается определенный дескриптор. Если семафор является групповым, задается число семафоров в группе. По
semget устанавливаются также права доступа к семафору.
После того, как дескриптор семафора установлен, процесс может производить операции над семафором с помощью
системного вызова semop, который передает указатель на структуру данных, определяющую набор операций. Этот набор включает
номер семафора в группе, вид конкретной операции над элементом семафора и флаги операции.
Unix допускает три вида операций над семафором:

Если величина semop положительна, то текущее значение семафора увеличивается на эту величину. Ресурс, контролируемый
данным семафором, освобождается.

Если значение semop равно нулю – процесс, выполнивший такой вызов, будет переведен в ожидание до тех пор, пока не
освободится ресурс, т.е. значение семафора не станет равным нулю.

Если величина semop отрицательна, процесс, вызвавший выполнение этой операции, ожидает, когда значение семафора не
станет большим или равным абсолютной величине semop. Затем абсолютная величина semop вычитается из значения
семафора. Эта операция используется при захвате ресурса..
1.7.8. Программные каналы.
Программные каналы – это средство обмена потоками информации между процессами. Идея программных каналов
используется для реализации конвейерной обработки информации, которая позволяет использовать вывод одной программы как ввод
для другой:
$com1 | com2 | com3
Существует два вида программных каналов:

неименованные программные каналы;

именованные программные каналы.

Неименованные программные каналы создаются только между процессами, которые порождены одним исходным (родительским)
процессом. Неименованный канал дескриптор передает порожденным дочерним процессам, после чего один процесс может писать
информацию в канал, а другой – читать из канала.
Именованный программный канал, после того как он будет создан, могут эксплуатировать все процессы, а не только процессы–
родственники, порожденные одним родительским процессом, для этого существует имя канала. Имя канала не передается по
наследству. Оно устанавливается один раз по команде пользователя. Процессы, которые собираются участвовать в обмене
информацией, должны знать это имя. Для создания каналов используются команды mknod или mkfifo. Процедура создания
именованных программных каналов описана позже в разделе Типы файлов.
Программный канал создается с помощью системного вызова pipe, который образует два дескриптора: один для записи в
канал, другой - для чтения из канала, после чего операции обмена информацией между процессами осуществляются с помощью
системных вызовов read/write.
Программный канал можно изобразить в виде трубы. На входе трубы действует процесс, который записывает информацию в
канал по системному вызову write. На выходе из трубы действует другой процесс, который читает информацию по системному вызову
read. Эта процедура показана на рисунке.
Родительский процесс
процесс
процесс
Программный канал
Действие программного канала.
Работает канал по схеме: первым вошел – первым вышел, то есть, та информация, которая была записана в канал раньше, будет раньше
считана. Это, так называемая, процедура FIFO (First In – First Out). Канал рассчитан на определенный объем информации (обычно 4096
байт). Если канал заполнен и никто из него не читает, процесс записи приостанавливается. Если информация из канала считана и в него
никто не пишет, приостанавливается процесс чтения.
Именованные программные каналы создаются только по командам пользователя. Запись в такие каналы и чтение из них организует
пользователь.
Неименованные программные каналы создаются автоматически, если пользователь применяет команды конвейеризации. Процесс
может устанавливать несколько программных каналов.
Прохождение информации в этом случае организуется в виде линейных или сетевых структур.
Именованные программные каналы обычно используются для реализации моделей “клиент – сервер”. В таком случае они являются
средством коммуникации между независимыми процессами.
1.7.9. Очереди сообщений.
Очереди сообщений являются средством обмена информацией между процессами, так же как и программные каналы.
Однако, в отличие от каналов, они допускают более гибкую организацию взаимодействия процессов.
При использовании очередей совсем необязательно существование парных процессов: «писателя» и «читателя». Просто
существует некоторая очередь сообщений, которая используется как хранилище сообщений для любых процессов, которые к ней
обращаются - и «читатели» и «писатели».
Очереди имеют свои преимущества по сравнению с программными каналами. Например, чтобы осуществить дуплексную
связь между двумя процессами, нужно создать два канала для каждого процесса: один для записи, а другой для чтения. В случае
использования очередей можно обойтись одной очередью, если различать сообщения по типу: от клиента к серверу и наоборот.
Кроме того, имеется возможность извлекать сообщения из очереди не только по принципу FIFO, но и в произвольном
порядке. Эта особенность открывает возможность построения системы с приоритетным обслуживанием.
Длина сообщений в очереди выбирается пользователем и может быть произвольной в пределах памяти, отведенной для
размещения очереди в момент ее создания. В сообщении допустимы любые данные.
Каждая очередь сообщений имеет свой уникальный идентификатор. Процессы могут записывать и считывать сообщения из
разных очередей. Процесс, пославший сообщение в очередь, может не ожидать чтения этого сообщения другим процессом. Оно может
быть прочитано другим процессом позже.
Каждый процесс имеет следующие атрибуты:

тип сообщения;

длина сообщения в байтах;

данные сообщения.
Для работы с очередями используются следующие системные вызовы:
Msgge
- создание очереди;
Msgctl
- установка параметров очереди;
Msgsnd - посылка сообщения в очередь;
Msgrcv - получение сообщений из очереди.
Типичный пример использования очередей при организации работы сервера по обмену данными с несколькими клиентами. Поскольку
очередь является объектом межпроцессного взаимодействия, к которому могут обращаться и процессы-«читатели» и процессы«писатели», то сообщения (запросы), направляемые от любого из клиентов, устанавливаются в очередь с признаком типа «от клиента к
серверу = 1». Кроме того, в таком сообщении устанавливается идентификатор клиента PID. Сервер, в свою очередь, может передать
сообщение конкретному клиенту, зная идентификатор клиента. Сервер будет принимать сообщения с типом 1, а клиенты – сообщения с
типами, равными идентификаторам.
1.7.9. Разделяемая память.
Разделяемую память применяют для того, чтобы увеличить скорость прохождения данных между процессами. Во всех
рассмотренных ранее случаях обмен информацией между процессами проходит через ядро. Техника разделяемой памяти позволяет
осуществить обмен информацией не через ядро, а, используя некоторую часть виртуального адресного пространства, куда помещаются
и откуда считываются данные.
После создания разделяемого сегмента памяти любой из процессов пользователей может подсоединить его к своему
собственному виртуальному пространству и работать с ним, как с обычным сегментом памяти. Недостатком такого обмена
информацией является отсутствие каких бы то ни было средств синхронизации, однако, для преодоления этого недостатка можно
использовать технику семафоров.
Примерный сценарий использования разделяемой памяти при реализации технологий «клиент - сервер» имеет вид:
1.
сервер получает доступ к разделяемой памяти, используя семафор;
2.
сервер производит запись данных в разделяемую память;
3.
после завершения записи данных сервер освобождает доступ к разделяемой памяти с помощью семафора;
4.
клиент получает доступ к разделяемой памяти, запирая доступ к этой памяти для других процессов с помощью семафора;
5.
клиент производит чтение данных из разделяемой памяти, а затем освобождает доступ к памяти с помощью семафора.
Для работы с разделяемой памятью используются системные вызовы:
- shmge - создание сегмента разделяемой памяти;
- shmctl - установка параметров;
- shmat - подсоединение сегмента памяти;
- shmdt - отсоединение сегмента.
В схеме обмена данными между двумя процессами (клиентом и сервером), использующими разделяемую память, должна
функционировать группа из двух семафоров. Первый семафор служит для блокирования доступа к разделяемой памяти, его
разрешающий сигнал – 1, а запрещающий – 0. второй семафор служит для сигнализации сервера о том, что клиент начал работу, при
этом доступ к разделяемой памяти блокируется и клиент читает данные из памяти. Теперь при вызове операции сервером, его работа
будет приостановлена до освобождения памяти клиентом.
Download