Основы операционных систем

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

Рубрика Программирование, компьютеры и кибернетика
Вид книга
Язык русский
Дата добавления 12.01.2010
Размер файла 2,6 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

1рсгт Бет <1РС идентификатор>

Для этой же цели мы можем применять системный вызов Бетси! (), который умеет выполнять и другие операции над массивом семафоров, но их рассмотрение выходит за рамки нашего курса.

Системный вызов semctJ() Прототип системного вызова

#include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h>

int semctl(int semid, int semnum, int and, union semun arg); Описание системного вызова

Системный вызов semctl предназначен для получения информации о массиве IPC семафоров, изменения его атрибутов и удаления его из системы. Данное описание не является полным описанием системного вызова, а ограничивается рамками текущего курса. Для изучения полного описания обращайтесь к UNIX Manual.

В нашем курсе мы будем применять системный вызов semctl только для удаления массива семафоров из системы. Параметр semid является дескриптором System V IPC для массива семафоров, т. е. значением, которое вернул системный вызов semget {) при создании массива или при его поиске по ключу.

В качестве параметра cmd в рамках нашего курса мы всегда будем передавать значение IFC_RMID - команду для удаления сегмента разделяемой памяти с заданным идентификатором. Параметры semnum и arg для этой команды не используются, поэтому мы всегда будем подставлять вместо них значение 0.

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

Возвращаемое значение

Системный вызов возвращает значение 0 при нормальном завершении и значение -1 при возникновении ошибки.

Написание, компиляция и прогон программы с организацией взаимоисключения с помощью

семафоров для двух процессов, взаимодействующих через разделяемую память

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

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

В материалах семинара 5, когда речь шла о связи родственных процессов через pipe, отмечалось, что pipe является однонаправленным каналом связи, и что для организации связи через один pipe в двух направлениях необходимо использовать механизмы взаимной синхронизации процессов. Организуйте двустороннюю поочередную связь процесса-родителя и процесса-ребенка через pipe, используя для синхронизации семафоры, модифицировав программу из раздела «Прогон программы для организации однонаправленной связи между родственными процессами через pipe» семинара 5.

Понятие о POSIX-семафорах

В стандарте POSIX вводятся другие семафоры, полностью аналогичные семафорам Дейкстры. Для инициализации значения таких семафоров применяется функция sem_init (), аналогом операции Р служит функция sem_wait (), а аналогом операции V -- функция sem_post (). К сожалению, в Linux такие семафоры реализованы только для нитей исполнения одного процесса, и поэтому подробно мы на них останавливаться не будем.

Семинар 9. Очереди сообщений в UNIX

Сообщения как средства связи и средства синхронизации процессов. Очереди сообщений в UNIX как составная часть System V IPC. Создание очереди сообщений или доступ к уже существующей. Системный вызов msgget (). Реализация примитивов send и receive. Системные вызовы msgsnd() и msgrcv(). Удаление очереди сообщений из системы с помощью команды ipcrm или системного вызова msgctl (). Понятие мультиплексирования. Мультиплексирование сообщений. Модель взаимодействия процессов клиент -- сервер. Неравноправность клиента и сервера. Использование очередей сообщений для синхронизации работы процессов.

Ключевые слова: очереди сообщений System V IPC, тип сообщения, выбор сообщений по типам, системные вызовы msgget (),

msgsnd(), msgrcv() и msgctl (), шаблон сообщения, мультиплексирование сообщений, модель клиент--сервер.

Сообщения как средства связи и средства синхронизации процессов

В материалах предыдущих семинаров были представлены такие средства организации взаимодействия процессов из состава средств System V IPC, как разделяемая память (семинары 6--7) и семафоры (семинар 8). Третьим и последним, наиболее семантически нагруженным средством, входящим в System V IPC, являются очереди сообщений. В лекции 6 говорилось о модели сообщений как о способе взаимодействия процессов через линии связи, в котором на передаваемую информацию накладывается определенная структура, так что процесс, принимающий данные, может четко определить, где заканчивается одна порция информации и начинается другая. Такая модель позволяет задействовать одну и ту же линию связи для передачи данных в двух направлениях между несколькими процессами. Мы также рассматривали возможность использования сообщений с встроенными механизмами взаимоисключения и блокировки при чтении из пустого буфера и записи в переполненный буфер для организации синхронизации процессов.

В материалах этого семинара речь пойдет об использовании очередей сообщений System V IPC для обеспечения обеих названных функций.

Очереди сообщений в UNIX как составная часть

System V IPC

Так как очереди сообщений входят в состав средств System V IPC, для них верно все, что говорилось ранее об этих средствах в целом, и уже знакомо нам. Очереди сообщений, как и семафоры, и разделяемая память, являются средством связи с непрямой адресацией, требуют инициализации для организации взаимодействия процессов и специальных действий для освобождения системных ресурсов по окончании взаимодействия. Пространством имен очередей сообщений является то же самое множество значений ключа, генерируемых с помощью функции f to к () (см. семинары 6--7 раздел «Пространство имен. Адресация в System V IPC. Функция ftok()»). Для выполнения примитивов send и receive, введенных в лекции 6, соответствующим системным вызовам в качестве параметра передаются IPC-дескрипторы (см. семинары 6--7 раздел «Дескрипторы System V 1РС») очередей сообщений, однозначно идентифицирующих их во всей вычислительной системе.

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

В порядке FIFO, независимо от типа сообщения.

В порядке FIFO для сообщений конкретного типа.

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

Реализация примитивов send и receive обеспечивает скрытое от пользователя взаимоисключение во время помещения сообщения в очередь или его получения из очереди. Также она обеспечивает блокировку процесса при попытке выполнить примитив receive над пустой очередью или очередью, в которой отсутствуют сообщения запрошенного типа, или при попытке выполнить примитив send для очереди, в которой нет свободного места.

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

Создание очереди сообщений или доступ к уже существующей. Системный вызов msggetO

Для создания очереди сообщений, ассоциированной с определенным ключом, или доступа по ключу к уже существующей очереди используется системный вызов msgget (), являющийся аналогом системных вызовов shmget () для разделяемой памяти и semget () для массива семафоров, который возвращает значение IPC-дескриптора для этой очереди. При этом существуют те же способы создания и доступа, что и для разделяемой памяти или семафоров (см. семинары 6--7 раздел «Разделяемая память в UNIX. Системные вызовы shmget(), shmat(), shmdt()» и семинар 8 раздел «Создание массива семафоров или доступ к уже существующему. Системный вызов semget()», соответственно).

Системный вызов msgget() Прототип системного вызова

#include <sys/types.h> ttinclude <sys/ipc.h> #include <sys/msg.h>

int msgget(key_t key, int msgflg); Описание системного вызова

Системный вызов msgget предназначен для выполнения операции доступа к очереди сообщений и, в случае ее успешного завершения, возвращает дескриптор System V IPC для этой очереди (целое неотрицательное число, однозначно характеризующее очередь сообщений внутри вычислительной системы и использующееся в дальнейшем для других операций с ней).

Параметр key является ключом System V IPC для очереди сообщений, т. е. фактически ее именем из пространства имен System V IPC. В качестве значения этого параметра может быть использовано значение ключа, полученное с помощью функции f tok (), или специальное значение IPC_PRIVATE. Использование значения IPC_PRIVATE всегда приводит к попытке создания новой очереди сообщений с ключом, который не совпадает со значением ключа ни одной из уже существующих очередей и не может быть получен с помощью функции f tok () ни при одной комбинации ее параметров.

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

IPC_CREAT - если очереди для указанного ключа не существует, она должна быть создана;

IPC_EXCL - применяется совместно с флагом IPC_CREAT. При совместном их использовании и существовании массива с указанным ключом доступ к очереди не производится и констатируется ошибочная ситуация; при этом переменная еггпо, описанная в файле <ermo.h>, примет значение EEXIST;

0400 - разрешено чтение для пользователя, создавшего очередь;

0200 - разрешена запись для пользователя, создавшего очередь;

0040 - разрешено чтение для группы пользователя, создавшего очередь;

0020 - разрешена запись для группы пользователя, создавшего очередь;

0004 - разрешено чтение для всех остальных пользователей;

0002 - разрешена запись для всех остальных пользователей.

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

ipcs -1

Возвращаемое значение

Системный вызов возвращает значение дескриптора System V IPC для очереди сообщений при нормальном завершении и значение -1 при возникновении ошибки.

Реализация примитивов send и receive. Системные вызовы msgsnd() и msgrcv()

Для выполнения примитива send используется системный вызов msgsnd (), копирующий пользовательское сообщение в очередь сообщений, заданную IPC-дескриптором. При изучении описания этого вызова обратите особое внимание на следующие моменты:

Тип данных struct msgbuf не является типом данных для пользовательских сообщений, а представляет собой лишь шаблон для создания таких типов. Пользователь сам должен создать структуру для своих сообщений, в которой первым полем должна быть переменная типа long, содержащая положительное значение типа сообщения.

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

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

Системный вызов msgsndO Прототип системного вызова

tinclude <sys/types.h> iinclude <sys/ipc.h> tinclude <sys/msg.h>

int msgsndfint msqid, struct msgbuf *ptr, int length, int flag);

Описание системного вызова

Системный вызов msgsnd предназначен для помещения сообщения в очередь сообщений, т. е. является реализацией примитива send.

Параметр msqid является дескриптором System V IPC для очереди, в которую отправляется сообщение, т. е. значением, которое вернул системный вызов msgget () при создании очереди или при ее поиске по ключу.

Структура struct msgbuf описана в файле <sys/msg.h> как

struct msgbuf { long mtype; char mtextfl];

};

Она представляет собой некоторый шаблон структуры сообщения пользователя. Сообщение пользователя - это структура, первый элемент которой обязательно имеет тип long и содержит тип сообщения, а далее следует информативная часть теоретически произвольной длины (практически в Linux она ограничена размером 4080 байт и может быть еще уменьшена системным администратором), содержащая собственно суть сообщения. Например:

struct mymsgbuf {

long mtype;

char mtext[1024]; } mybuf;

При этом информация вовсе не обязана быть текстовой, например:

struct mymsgbuf {

: long mtype; struct { int iinfo; float finfo; } info; } mybuf;

Тип сообщения должен быть строго положительным числом. Действительная дпина полезной части информации (т. е. информации, расположенной в структуре после типа сообщения) должна быть передана системному вызову в качестве параметра length. Этот параметр может быть равен и 0, если вся полезная информация заключается в самом факте наличия сообщения. Системный вызов копирует сообщение, расположенное по адресу, на который указывает параметр ptr, в очередь сообщений, заданную дескриптором msqid.

Параметр flag может принимать два значения: 0 и IPC_NOWAIT. Если значение флага равно 0, и в очереди не хватает места для того, чтобы поместить сообщение, то системный вызов блокируется до тех пор, пока не освободится место. При значении флага I PC_NOWAIT системный вызов в этой ситуации не блокируется, а констатирует возникновение ошибки с установлением значения переменной еггпо, описанной в файле <errno. h>, равным EAGAIN.

Возвращаемое значение

Системный вызов возвращает значение 0 при нормальном завершении и значение -1 при возникновении ошибки.

Примитив receive реализуется системным вызовом msgrcv(). При изучении описания этого вызова нужно обратить особое внимание на следующие моменты:

Тип данных struct msgbuf, как и для вызова msgsnd(), является лишь шаблоном для пользовательского типа данных.

Способ выбора сообщения (см. раздел «Очереди сообщений в UNIX как составная часть System V 1РС» текущего семинара) задается нулевым, положительным или отрицательным значением параметра type. Точное значение типа выбранного сообщения можно определить из соответствующего поля структуры, в которую системный вызов скопирует сообщение.

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

Выбранное сообщение удаляется из очереди сообщений.

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

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

Системный вызов msgrcvO

Прототип системного вызова

tinclude <sys/types.h> tinclude <sys/ipc.h> tinclude <sys/msg.h>

int msgrcvfint msqid, struct msgbuf *ptr, int length, long type, int flag);

Описание системного вызова

Системный вызов msgrcv предназначен для получения сообщения из очереди сообщений, т. е. является реализацией примитива receive.

Способ выборки

Значение параметра type

В порядке ЯН), независимо от типа сообщения

0

В порядке ЯЮ для сообщений с типом п

п

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

-п

Параметр msqid является дескриптором System V IPC для очереди, из которой должно быть получено сообщение, т. е. значением, которое вернул системный вызов msgget () при создании очереди или при ее поиске по ключу.

Параметр type определяет способ выборки сообщения из очереди следующим образом.

Структура struct msgbuf описана в файле <sys/msg.h> как

struct msgbuf { long mtype; char mtext[l];

};

Она представляет собой некоторый шаблон структуры сообщения пользователя. Сообщение пользователя - это структура, первый элемент которой обязательно имеет тип long и содержит тип сообщения, а далее следует информативная часть теоретически произвольной длины (практически в Linux она ограничена размером 4080 байт и может быть еще уменьшена системным администратором), содержащая собственно суть сообщения. Например:

struct mymsgbuf {

long mtype;

char mtext[1024); } mybuf;

При этом информация вовсе не обязана быть текстовой, например:

struct mymsgbuf { long mtype; struct {

int iinfo; float finfo; } info; } mybuf;

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

В случае удачи системный вызов копирует выбранное сообщение из очереди сообщений по адресу, указанному в параметре ptr, одновременно удаляя его из очереди сообщений.

Параметр flag может принимать значение 0 или быть какой-либо комбинацией флагов IPC_NOWAIT и MSG_NOERROR. Если флаг IPC_NOWAIT не установлен и очередь сообщений пуста или в ней нет сообщений с заказанным типом, то системный вызов блокируется до появления запрошенного сообщения. При установлении флага IPC_NOWAIT системный вызов в этой ситуации не блокируется, а констатирует возникновение ошибки с установлением значения переменной ептю, описанной в файле <errno. h>, равным EAGAIN. Если действительная длина полезной части информации в выбранном сообщении превышает значение, указанное в параметре length и флаг MSG_NOERROR не установлен, то выборка сообщения не производится, и фиксируется наличие ошибочной ситуации. Если флаг MSG_NOERROR установлен, то в этом случае ошибки не возникает, а сообщение копируется в сокращенном виде.

Возвращаемое значение

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

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

ipcs -1

Удаление очереди сообщений из системы с помощью команды ipcrm или системного вызова msgctl()

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

ipcrm msg <1РС идентификатор>

Для получения IPC-идентификатора очереди сообщений примените команду ipcs. Можно удалить очередь сообщений и с помощью системного вызова msgctl (). Этот вызов умеет выполнять и другие операции над очередью сообщений, но в рамках данного курса мы их рассматривать не будем. Если какой-либо процесс находился в состоянии ожидание при выполнении системного вызова msgrcv () или msgsnd () для удаляемой очереди, то он будет разблокирован, и системный вызов констатирует наличие ошибочной ситуации.

Системный вызов msgctlO Прототип системного вызова

#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h>

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

Описание системного вызова

Системный вызов msgctl предназначен для получения информации об очереди сообщений, изменения ее атрибутов и удаления из системы. Данное описание не является полным описанием системного вызова, а ограничивается рамками текущего курса. Для изучения полного описания обращайтесь к UNIX Manual.

В нашем курсе мы будем пользоваться системным вызовом msgctl только для удаления очереди сообщений из системы. Параметр msgid является дескриптором System V IPC для очереди сообщений, т. е. значением, которое вернул системный вызов msgget () при создании очереди или при ее поиске по ключу.

В качестве параметра сш в рамках нашего курса мы всегда будем передавать значение IPC_RMID - команду для удаления очереди сообщений с заданным идентификатором. Параметр buf для этой команды не используется, поэтому мы всегда будем подставлять туда значение NULL.

Возвращаемое значение

Системный вызов возвращает значение 0 при нормальном завершении и значение -1 при возникновении ошибки.

Прогон примера с однонаправленной передачей текстовой информации

Для иллюстрации сказанного рассмотрим две простые программы:

/* Программа 09-1а.с для иллюстрации работы с очередями сообщений */

/* Эта программа получает доступ к очереди сообщений, отправляет в нее 5 текстовых сообщений с типом 1 и одно пустое сообщение с типом '2 55, которое будет служить для программы 09-1Ь.с сигналом прекращения работы. */ #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <string.h> #include <stdio.h>

#define LAST_MESSAGE 2 55 /* Тип сообщения для

прекращения работы программы 09-1Ь.с */ int main() {

int msqid; /* IPC-дескриптор для очереди сообщений */ char pathname[] = "09-la.c"; /* Имя файла,

использующееся для генерации ключа. Файл с таким

именем должен существовать в текущей директории */ key_t key; /* IPC ключ */ int i,len; /* Счетчик цикла и длина

информативной части сообщения */ /* Ниже следует пользовательская структура для

сообщения */ struct mymsgbuf {

long mtype; char mtext[81]; } mybu f;

/* Генерируем IPC-ключ из имени файла 09-1а.с в текущей директории и номера экземпляра очереди сообщений 0. */

if((key = ftok(pathname,0)) < 0){ printf("Can\1t generate key\n"); exit(-1);

}

/* Пытаемся получить доступ по ключу к очереди сообщений, если она существует, или создать ее, с правами доступа read & write для всех пользователей */

if((msqid = msgget(key, 0666 I IPC_CREAT)) < 0){ printf("Can\'t get msqid\n"); exit(-1);

}

/* Посылаем в цикле пять сообщений с типом 1 в очередь сообщений, идентифицируемую msqid.*/ for (i = 1; i <= 5; i + +) {

/* Сначала заполняем структуру для нашего сообщения и определяем длину информативной части */ mybuf.mtype = 1;

strcpy(mybuf.mtext, "This is text message"); len = strlen(mybuf.mtext)+1;

/* Отсылаем сообщение. В случае ошибки сообщаем об этом и удаляем очередь сообщений из системы. */ if (msgsnd(msqid, (struct msgbuf *) &mybuf, len, 0) < 0) {

printf("Can\'t send message to queue\n"); msgctl(msqid, IPC_RMID,

(struct msqid_ds *) NULL);

exit(-1);

}

}

/* Отсылаем сообщение, которое заставит получающий процесс прекратить работу, с типом LAST_MESSAGE и длиной 0 */

mybuf.mtype = LAST_MESSAGE; len = 0;

if (msgsnd(msqid, (struct msgbuf *) &mybuf, len, 0) < 0){

printf("Can\1t send message to queue\n"); msgctl(msqid, IPC_RMID,

(struct msqid_ds *) NULL); exit(-1);

}

return 0;

/* Программа 09-lb.c для иллюстрации работы с очередями сообщений */

/* Эта программа получает доступ к очереди сообщений и читает из нее сообщения с любым типом в порядке FIFO до тех пор, пока не получит сообщение с типом 2 55, которое будет служить сигналом прекращения работы. */ #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <string.h> #include <stdio.h>

#define LAST_MESSAGE 255 /* Тип сообщения для

прекращения работы */ int main() {

int msqid; /* IPC-дескриптор для очереди сообщений */ char pathname [] = "09-la.c"; /* Имя файла,

использующееся для генерации ключа. Файл с таким именем должен существовать в текущей директории */ key_t key; /* IPC ключ */

int len, maxlen; /* Реальная длина и максимальная

длина информативной части сообщения */ /* Ниже следует пользовательская структура для сообщения */

struct mymsgbuf {

long mtype; char mtext[81]; } mybu f;

/* Генерируем IPC-ключ из имени файла 09-1а.с в текущей директории и номера экземпляра очереди сообщений 0 */

if((key = ftok(pathname,0)) < 0){ printf("Can\'t generate key\n"); exit(-1) ;

}

/* Пытаемся получить доступ по ключу к очереди сообщений, если она существует, или создать ее, с правами доступа read & write для всех пользователей */

if((msqid = msgget(key, 0666 I IPC_CREAT)) < 0){ printf("Can\'t get msqid\n"); exit (-1) ;

}

while(1){

/* В бесконечном цикле принимаем сообщения любого типа в порядке FIFO с максимальной длиной информативной части 81 символ до тех пор, пока не поступит сообщение с типом LAST_MESSAGE*/ max1en = 81; if(( len = msgrcv(msqid,

(struct msgbuf *) &mybuf, maxlen, 0, 0) < 0){ printf("Can\'t receive message from queue\n"); exit(-1) ;

}

/* Если принятое сообщение имеет тип LAST_MESSAGE, прекращаем работу и удаляем очередь сообщений из системы. В противном случае печатаем текст принятого сообщения. */ if (mybuf.mtype == LAST_MESSAGE){

msgctl(msqid, IPC_RMID,

(struct msqid_ds *) NULL); exit(0); }

printf("message type = %ld, info = %s\n", mybuf.mtype, mybuf.mtext);

}

return 0; /* Исключительно для отсутствия warning'ов при компиляции. */

}

Первая из этих программ посылает пять текстовых сообщений с типом 1 и одно сообщение нулевой длины с типом 2 55 второй программе. Вторая программа в цикле принимает сообщения любого типа в порядке FIFO и печатает их содержимое до тех пор, пока не получит сообщение с типом 2 5 5. Сообщение с типом 2 55 служит для нее сигналом к завершению работы и ликвидации очереди сообщений. Если перед запуском любой из программ очередь сообщений еще отсутствовала в системе, то программа создаст ее.

Обратите внимание на использование сообщения с типом 2 55 в качестве сигнала прекращения работы второго процесса. Это сообщение имеет нулевую длину, так как его информативность исчерпывается самим фактом наличия сообщения.

Наберите программы, сохраните под именами 09-1а.с и 09-1Ь.с соответственно, откомпилируйте и проверьте правильность их поведения.

Модификация предыдущего примера для передачи числовой информации

В описании системных вызовов msgsnd () и msgrcv () говорится о том, что передаваемая информации не обязательно должна представлять собой текст.

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

struct mymsgbuf { long mtype; struct {

short sinfo; float finfo; } info; } mybu f;

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

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

sizeof(info)>=sizeof(short)+sizeof(float)

Для полной передачи информативной части сообщения в качестве длины нужно указывать не сумму длин полей, а полную длину структуры. Модифицируйте предыдущие программы 09-1а.с и 09-1Ь.с из раздела «Прогон примера с однонаправленной передачей текстовой информации» для передачи нетекстовых сообщений.

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

Наличие у сообщений типов позволяет организовать двустороннюю связь между процессами через одну и ту же очередь сообщений. Процесс 1 может посылать процессу 2 сообщения с типом 1, а получать от него сообщения с типом 2. При этом для выборки сообщений в обоих процессах следует пользоваться вторым способом выбора (см. раздел «Очереди сообщений в UNIX как составная часть System V IPC»). Напишите, откомпилируйте и прогоните программы, осуществляющие двустороннюю связь через одну очередь сообщений.

Понятие мультиплексирования. Мультиплексирование сообщений. Модель взаимодействия процессов клиент -- сервер. Неравноправность клиента и сервера

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

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

Сервер ждет запроса от клиентов, инициатором же взаимодействия является клиент.

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

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

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

Написание, компиляция и прогон программ клиента и сервера

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

Использование очередей сообщений для синхронизации работы процессов

В лекции 6 была доказана эквивалентность очередей сообщений и семафоров в системах, где процессы могут использовать разделяемую память. В частности, было показано, как реализовать семафоры с помощью очередей сообщений. Для этого вводился специальный синхронизирующий процесс-сервер, обслуживающий переменные-счетчики для каждого семафора. Процессы-клиенты для выполнения операции над семафором посылали процессу-серверу запросы на выполнение операции и ожидали ответа для продолжения работы. Теперь мы знаем, как это можно сделать в операционной системе UNIX и как, следовательно, можно использовать очереди сообщений для организации взаимоисключений и взаимной синхронизации процессов.

Задача повышенной сложности: реализуйте семафоры через очереди сообщений.

Семинары 10-11. Организация файловой системы в UNIX. Работа с файлами и директориями. Понятие о memory mapped файлах

Разделы носителя информации (partitions) в UNIX. Логическая структура файловой системы и типы файлов в UNIX. Организация файла на диске в UNIX на примере файловой системы s5fs. Понятие индексного узла (inode). Организация директорий (каталогов) в UNIX. Понятие суперблока. Операции над файлами и директориями. Системные вызовы и команды для выполнения операций над файлами и директориями. Системный вызов ореп(). Системный вызов close(). Операция создания файла. Системный вызов с г eat (). Операция чтения атрибутов файла. Системные вызовы stat (), f stat () и lstat (). Операции изменения атрибутов файла. Операции чтения из файла и записи в файл. Операция изменения указателя текущей позиции. Системный вызов lseek(). Операция добавления информации в файл. Флаг 0_APPEND. Операции создания связей. Команда In, системные вызовы link() и symlink(). Операция удаления связей и файлов. Системный вызов unlink (). Специальные функции для работы с содержимым директорий. Понятие о файлах, отображаемых в память (memory mapped файлах). Системные вызовы mmap(), munmap().

Ключевые слова: разделы (partitions) или логические диски, регулярные файлы, директории, файлы типа FIFO, файлы устройств, файлы типа «связь», файлы типа «сокет», граф файловой системы, корневая директория, полное имя файла, файловая система s5fs, заголовок раздела, индексный узел (inode), массив индексных узлов, атрибуты файла, суперблок, операции над файлами, указатель текущей позиции, таблица открытых файлов процесса, системная таблица открытых файлов, таблица индексных узлов открытых файлов, жесткая связь, мягкая или символическая связь, команды chmod, chgrp, chown, ср, rm, Is, mv, In, системные вызовы open ( ) , closed, read ( ) , write ( ) , created, stat ( ), lstat (), f stat ( ), lseekd, link(), symlink(), unlinkd, ftruncated, операции над директориями, функции opendird, readdird, rewinddird, closedird, файлы, отображаемые в память (memory mapped файлы), системные вызовы mmap(),munmap().

Введение

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

Разделы носителя информации (partitions) в UNIX

Физические носители информации -- магнитные или оптические диски, ленты и т. д., использующиеся как физическая основа для хранения файлов, в операционных системах принято логически делить на разделы (partitions) или логические диски. Причем слово «делить» не следует понимать буквально, в некоторых системах несколько физических дисков могут быть объединены в один раздел. Об этом подробнее рассказывается в лекции 12 в разделе «Общая структура файловой системы».

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

Наличие нескольких разделов на диске может определяться требованиями операционной системы или пожеланиями пользователя. Допустим, пользователь хочет разместить на одном жестком диске несколько операционных систем с возможностью попеременной работы в них, тогда он размещает каждую операционную систему в своем разделе. Или другая ситуация: необходимость работы с несколькими видами файловых систем. Под каждый тип файловой системы выделяется отдельный логический диск. Третий вариант -- это разбиение диска на разделы для размещения в разных разделах различных категорий файлов. Скажем, в одном разделе помещаются все системные файлы, а в другом разделе -- все пользовательские файлы. Примером операционной системы, внутренние требования которой приводят к появлению нескольких разделов на диске, могут служить ранние версии MS-DOS, для которых максимальный размер логического диска не превышал 32 Мбайт.

Для простоты далее в этих семинарах будем полагать, что у нас имеется только один раздел и, следовательно, одна файловая система. Вопросы взаимного сосуществования нескольких файловых систем в рамках одной операционной системы мы затронем в семинарах 13--14 перед обсуждением реализации подсистемы ввода-вывода.

Логическая структура файловой системы и типы файлов в UNIX

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

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

обычные или регулярные файлы;

директории или каталоги;

файлы типа FIFO или именованные pip'bi;

специальные файлы устройств;

сокеты (sockets);

специальные файлы связи (link).

Что такое регулярные файлы и директории, вам должно быть хорошо известно из личного опыта и из лекций (лекция 11). О способах их отображения в дисковое пространство речь пойдет чуть позже. Файлы типа FIFO были представлены в семинаре 5, когда рассматривалась работа с именованными pip'aMH (раздел «Понятие FIFO. Использование системного вызова mknod() для создания FIFO. Функция mkfifo()»). Файлы типа «связь» мы представим в этом семинаре, когда будем обсуждать операции над файлами (раздел «Операции над файлами и директориями») и соответствующие им системные вызовы (раздел «Системные вызовы и команды для выполнения операций над файлами и директориями»). О специальных файлах устройств будет рассказано в материалах семинаров 12--13, посвященных реализации в UNIX подсистемы ввода-вывода и передаче информации с помощью сигналов. Файлы типа «сокет» будут введены в семинарах 14--15, когда мы будем рассматривать вопросы сетевого программирования в UNIX.

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

Рис. 10-11.1. Пример графа файловой системы

В отличие от древовидной структуры набора файлов, где имена файлов связывались с узлами дерева, в таком ациклическом графе имя файла связывается не с узлом, соответствующим файлу, а с входящим в него ребром. Ребра, выходящие из узлов, соответствующих файлам типа «связь», являются неименованными. Надо отметить, что практически во всех существующих реализациях UNIX-подобных систем в узел графа, соответствующий файлу типа «директория», не может входить более одного именованного ребра, хотя стандарт на операционную систему UNIX и не запрещает этого. Правила построения имен ребер (файлов) рассматривались в семинарах 1--2. В качестве полного имени файла может использоваться любое имя, получающееся при прохождении по ребрам от корневого узла графа (т. е. узла, в который не входит ни одно ребро) до узла, соответствующего этому файлу, по любому пути с помощью следующего алгоритма:

Если интересующему нас файлу соответствует корневой узел, то файл имеет имя «/».

Берем первое именованное ребро в пути и записываем его имя, которому предваряем символ «/».

Для каждого очередного именованного ребра в пути приписываем к уже получившейся строке справа символ «/» и имя соответствующего ребра.

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

Организация файла на диске в UNIX на примере файловой системы s5fs. Понятие индексного узла (inode) директория регулярный файл файл типа «связь» файл типа FIFO файл типа «устройство» файл типа «сокет»

Рассмотрим, как организуется на физическом носителе любой файл в UNIX на примере простой файловой системы, впервые появившейся в вариантах операционной системы System V и носящей поэтому название s5fs (system V file system).

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

Для размещения любого файла на диске используется метод индексных узлов (inode -- от index node), о котором подробно рассказывается в лекции 12 (раздел «Методы выделения дискового пространства»), и на котором здесь мы останавливаться не будем. Индексный узел содержит атрибуты файла и оставшуюся часть информации о его размещении на диске. Необходимо, однако, отметить, что такие типы файлов, как «связь», «сокет», «устройство», «FIFO» не занимают на диске никакого иного места, кроме индексного узла (им не выделяется логических блоков). Все необходимое для работы с этими типами файлов содержится в их атрибутах.

Перечислим часть атрибутов файлов, хранящихся в индексном узле и свойственных большинству типов файлов. К таким атрибутам относятся:

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

Идентификаторы владельца-пользователя и владельца-группы.

Размер файла в байтах (только для регулярных файлов, директорий и файлов типа «связь»).

Время последнего доступа к файлу.

Время последней модификации файла.

* Время последней модификации самого индексного узла. Существует еще один атрибут, о котором мы поговорим в этих семинарах позже, когда будем рассматривать операцию связывания файлов в разделе «Системные вызовы и команды для выполнения операций над файлами и директориями». Количество индексных узлов в разделе является постоянной величиной, определяемой на этапе генерации файловой системы. Все индексные узлы системы организованы в виде массива, хранящегося в заголовке раздела. Каждому файлу соответствует только один элемент этого массива и, наоборот, каждому непустому элементу этого массива соответствует только один файл. Таким образом, каждый файл на диске может быть однозначно идентифицирован номером своего индексного узла (его индексом в массиве).

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

Надо отметить, что свойством уникальности номеров индексных узлов, идентифицирующих файлы, мы уже неявно пользовались при работе с именоваными pip'aMH (семинар 5, раздел «Понятие FIFO. Использование системного вызова mknod() для создания FIFO. Функция mkfifo()») и средствами System V IPC (семинары 6--7, раздел «Понятие о System V IPC»). Для именованного pip'a именно номер индексного узла, соответствующего файлу с типом FIFO, является той самой точкой привязки, пользуясь которой, неродственные процессы могут получить данные о расположении pip'a в адресном пространстве ядра и его состоянии и связаться друг с другом. Для средств System V IPC при генерации IPC-ключа с помощью функции f to к () в действительности используется не имя заданного файла, а номер соответствующего ему индексного дескриптора, который по определенному алгоритму объединяется с номером экземпляра средства связи.

Организация директорий (каталогов) в UNIX

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

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

В файловой системе s5fs пространство имен файлов (ребер) содержит имена длиной не более 14 символов, а максимальное количество inode в одном разделе файловой системы не может превышать значения 65535. Эти ограничения не позволяют давать файлам осмысленные имена и приводят к необходимости разбиения больших жестких дисков на несколько разделов. Зато они помогают упростить структуру хранения информации в директории. Все содержимое директории представляет собой таблицу, в которой каждый элемент имеет фиксированный размер в 16 байт. Из них 14 байт отводится под имя соответствующего файла (ребра), а 2 байта -- под номер его индексного узла. При этом первый элемент таблицы дополнительно содержит ссылку на саму данную директорию под именем «.», а второй элемент таблицы -- ссылку на родительский каталог (если он существует), т. е. на узел графа, из которого выходит единственное именованное ребро, ведущее к текущему узлу, под именем «..».

В более современной файловой системе FFS (Fast File System) размерность пространства имен файлов (ребер) увеличена до 255 символов. Это позволило использовать практически любые мыслимые имена для файлов (вряд ли найдется программист, которому будет не лень набирать для имени более 255 символов), но пришлось изменить структуру каталога (чтобы уменьшить его размеры и не хранить пустые байты). В системе FFS каталог представляет собой таблицу из записей переменной длины. В структуру каждой записи входят: номер индексного узла, длина этой записи, длина имени файла и собственно его имя. Две первых записи в каталоге, как и в s5fs, по-прежнему адресуют саму данную директорию и ее родительский каталог.


Подобные документы

  • Основные понятия об операционных системах. Виды современных операционных систем. История развития операционных систем семейства Windows. Характеристики операционных систем семейства Windows. Новые функциональные возможности операционной системы Windows 7.

    курсовая работа [60,1 K], добавлен 18.02.2012

  • Понятие виртуальной памяти, ее реализация. Особенности страничной организации по требованию. Этапы обработки ситуации отсутствия страницы в памяти. Стратегии (алгоритмы) замещения страниц. Особенности некоторых операционных систем: Windows NT и Solaris.

    презентация [2,2 M], добавлен 24.01.2014

  • Изучение особенностей операционной системы, набора программ, контролирующих работу прикладных программ и системных приложений. Описания архитектуры и программного обеспечения современных операционных систем. Достоинства языка программирования Ассемблер.

    презентация [1,3 M], добавлен 22.04.2014

  • Общая характеристика преимуществ взаимодействующих процессов: модульность, ускорение вычислений. Знакомство с основами современных операционных систем. Анализ особенностей использования общего почтового ящика, рассмотрение способов создания и удаления.

    презентация [1,6 M], добавлен 24.01.2014

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

    курсовая работа [36,4 K], добавлен 08.01.2011

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

    реферат [16,6 K], добавлен 25.02.2011

  • Важность операционной системы для мобильных устройств. Популярность операционных систем. Доля LINUX на рынке операционных систем. История OS Symbian, BlackBerry OS, Palm OS. Отличия смартфона от обычного мобильного телефона. Учет ограничений по памяти.

    презентация [477,3 K], добавлен 01.12.2015

  • Основные понятия операционных систем. Современное оборудование компьютера. Преимущества и недостатки операционной системы Linux. Функциональные возможности операционной системы Knoppix. Сравнительная характеристика операционных систем Linux и Knoppix.

    реферат [1,5 M], добавлен 17.12.2014

  • Основные понятия операционных систем. Синхронизация и критические области. Сигналы и взаимодействие между процессами. Управление памятью. Драйверы устройств. Особенности современных операционных систем. Центральный процессор, микросхемы часов и таймеров.

    учебное пособие [1,2 M], добавлен 24.01.2014

  • Использование операционных систем Microsoft Windows. Разработка операционной системы Windows 1.0. Возможности и характеристика последующих версий. Выпуск пользовательских операционных систем компании, доработки и нововведения, версии Windows XP и Vista.

    реферат [23,3 K], добавлен 10.01.2012

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.