Главная страница

Ответы по экзамену операционные системы. Для удобства


Скачать 191.51 Kb.
НазваниеДля удобства
АнкорОтветы по экзамену операционные системы
Дата29.10.2022
Размер191.51 Kb.
Формат файлаdocx
Имя файлаOtvety_po_OS.docx
ТипДокументы
#761250
страница14 из 14
1   ...   6   7   8   9   10   11   12   13   14

Какая команда используется для создания пакета deb? Какая команда используется для установки программ в Debian? Какая команда используется для установки rpm пакета?


Создаем папку программы, в ней создаем папку DEBIAN, в котором находится файл control, далее создаем папку, в которую установится приложение, начиная с корня: supersh/usr/bin/

Команда создания пакета: fakeroot dpkg-deb --build supers

Команда установки: sudo dpkg -i zip_3.0-4_i386.deb

Установка rpm: sudo rpm -i имя_пакета.rpm

  1. Какие ключи безусловно необходимы в командной строке вызова компилятора gcc?


gcc program.c –o program.out,

-o куда сложить откомпилированный файл

  1. Какая библиотека подключается при компилировании программ по умолчанию?


Стандартная библиотека языка Си (также известная как libc, crt), c89, std=gnu89

  1. В чём отличие с точки зрения организации многозадачности дочерних процессов, запущенных с помощью функций семейства spawn*() и функций *fork()?


spawn*() - семейство функций для создания новых процессов, имена соответствующих выполняемых файлов задаются как параметры.

fork() создаёт точную копию вызывающего процесса. Дочь получает свой уникальный идентификатор процесса PID и наследует файловые дескрипторы и открытые потоки директорий родителя.

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


Для этих целей предусмотрена утилита on. Для задания приоритета и политики планирования используется ключ –p.

Примеры. запустить программу prg.out с уровнем приоритета 9: on –p 9 ./prg.out. Запустить программу prg.out с уровнем приоритета 15, политикой планирования FIFO, передав программе аргументы arg1 и arg2 on –p 15f ./prg.out arg1 arg2.

f— FIFO

r— round-robin

s— sporadic

  1. Каким образом можно заставить родительский поток не занимать процессорные ресурсы во время выполнения дочерних потоков в едином или отдельном процессе?


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

spawnl (P_WAIT, "/bin/ls", "/bin/ls", NULL)– ждем, пока выполнится программа

pthread_create(), pthread_join()

  1. С помощью каких функций поток может узнать свои собственные идентификатора процесса и потока?


Pid getpid () id процесса

Tid - pthread_self() id потока

  1. Как можно узнать идентификатор дочернего процесса. создаваемого с помощью функции fork()?


if (child_pid = fork ()) { //если fork() == 0, то потомок, иначе – родитель

  1. Какие характеристики запускаемого процесса можно задать в параметрах утилиты on?


Для задания приоритета и политики планирования используется ключ –p.

Запустить программу prg.out с уровнем приоритета 15, политикой планирования FIFO, передав программе аргументы arg1 и arg2 on –p 15f ./prg.out arg1 arg2.

f— FIFO

r— round-robin

s— sporadic

  1. Чем принципиально различаются мьютексы и семафоры при использовании их для взаимного исключения?


Мьютекс используется в случаях, когда имеется единственный экземпляр объекта (или как OP, упомянутый доступ к разделу критического кода), который необходимо синхронизировать. Пример: один производитель-потребитель, обращающийся к блоку очереди/памяти. Если в настоящее время производитель блокирует мьютекс. Пользователь будет заблокирован (заблокирован) от его использования до тех пор, пока производитель не выпустит его.

Семафор используется в случаях, когда имеется несколько экземпляров общих ресурсов. Поэтому, когда новый ресурс добавлен, мы делаем sem_post и когда ресурс берется или используется sem_wait (декремент). Когда счетчик окажется ниже 0, команда shm_wait будет заблокирована. Это пример в системе V.

  1. Будет ли доступен именованный семафор для открывших его процессов после вызова функции sem_unlink()?


sem_unlink(…) - удалить из системы именованный семафор. После вызова этой функции семафор остаётся доступным для процессов, которые открыли его, но исчезает сразу, как только последний из этих процессов вызовет sem_close().

  1. Опишите словами, как можно реализовать примитив синхронизации барьер, используя условную переменную.


Барьер — один из примитивов синхронизации. Он создаётся на некоторое количество потоков. Когда первый поток завершает свою работу, то он остаётся ждать у барьера и ждёт, пока не завершат работу остальные потоки.

Как только у барьера накапливается ровно столько потоков, на сколько был создан барьер, все потоки, которые ожидают у барьера, продолжают свою работу.

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

  1. Какие нюансы поведения делают условную переменную похожей на семафор?


В коде программы это выглядит так:

while (условие) pthread_cond_wait(…);

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

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


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

-поступил сигнал по условной переменной, и

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

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


-pthread_cond_signal(…) – разблокировать ожидающий на условной переменной поток. Этот поток – либо с наивысшим приоритетом в очереди к условной переменной, либо (при совпадении приоритетов) – тот, который ждёт дольше всех,

-pthread_cond_broadcast(…) – разблокировать все ожидающие на условной переменной потоки. Потоки разблокируются либо в порядке приоритетов, либо (при совпадении приоритетов) – в порядке FIFO

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


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







Сервер

Клиент

1. Создаёт канал. Системный вызов

int ChannelCreate(unsigned flags);

Аргумент flags задаёт отдельные режимы

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

Возвращаемое значение – идентификатор канала chid.

2. Ждёт запроса от клиентов. Системный вызов int MsgReceive( int chid, void * msg, int bytes, struct

_msg_info * info );

Аргумент msg – указатель на буфер, куда помещается полученное сообщение, bytes – размер буфера (размер должен быть достаточным для получаемого сообщения). info – указатель на структуру, в которой размещается дополнительная информация о сообщении, в лабораторной работе эта информация не нужна, будем принимать NULL.

Если в момент вызова MsgReceive() в канале имеются сообщения, они принимаются сразу без блокирования сервера в порядке их приоритетов (поток сервера наследует приоритет потока, пославшего сообщение). Если сообщений в канале нет, сервер блокируется в состоянии RECEIVE до тех пор, пока сообщение не поступит. Если MsgReceive() отработал без ошибок, он возвращает идентификатор получателя ответа rcvid.

3. После получения запроса сервер обрабатывает запрос клиента, готовит и отправляет ответ.

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

int MsgReply(int rcvid, int status, const void* msg, int size);

Аргументы: msg – указатель на подготовленное сообщение-ответ размером size, status может быть использован в клиентском вызове MsgSend().

Если в ответ клиенту ничего возвращать не нужно, вместо MsgReply() можно использовать MsgError().

1. Присоединяется к каналу. Системный вызов int ConnectAttach(uint32_t nd, pid_t pid, int chid, unsigned index, int flags );

Первая тройка аргументов – важнейшая, сокращённо обозначаемая nd-pid-chid, делает известным клиенту узел сети nd, на котором расположен процесс-сервер, идентификатор процесса-сервера pid, и идентификатор созданного сервером канала chid. Системный вызов возвращает идентификатор соединения connection ID (coid), который рассматривается как файловый дескриптор. Чтобы не возникло конфликтов между уже существующими дескрипторами и coid, аргументу index рекомендуется задавать значение _NTO_SIDE_CHANNEL.

Значение flags можно взять равным 0. В программах настоящей лабораторной работы все обменивающиеся сообщениями потоки расположены на одном компьютере, что соответствует значению nd = 0. Значения рid и chid известны из процесса – сервера.

2. Посылает сообщение-запрос серверу. Системный вызов int MsgSend( int coid, const void* smsg, int sbytes, void* rmsg, int rbytes );

Аргумент smsg – указатель на буфер, в котором находится посылаемое сообщение, sbytes – размер этого буфера, rmsg – указатель на буфер, куда помещается полученный от сервера ответ, bytes – размер буфера для сообщения-ответа. После посылки запроса клиент входит в блокированное состояние. Если сервер сразу принимает посланное клиентом сообщение в своё адресное пространство, клиент становится REPLYблокированным в ожидания ответа. Если сервер после посылки клиентом сообщения не готов сразу его принять, клиент входит в SEND-блокированное состояние, и становится в очередь к серверу (возможно, с другими потоками-клиентами). Состояние SEND сменяется состоянием REPLY, как только сервер примет сообщение.

Вызов возвращает значение status от MsgReply() сервера.









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


nd-pid-chid

nd - узел сети для клиента на котором расположен процесс-сервер

pid - идентификатор процесса-сервера

chid - идентификатор созданного сервером канала chid.

  1. На какой вид сообщения серверу отвечать не нужно?


На импульс.

Возвращаемое значение при приёме импульса 0 вместо rcvid, отвечать на импульс не надо.

  1. Какой системный вызов может использовать сервер, если ему надо просто разблокировать клиента без отправки ему содержательного ответа?


Если в ответ клиенту ничего возвращать не нужно, вместо MsgReply() можно использовать MsgError().

  1. В каких состояниях может находиться поток-клиент после отправки сообщения серверу?


REPLY SEND

После посылки запроса клиент входит в блокированное состояние. Если сервер сразу принимает посланное клиентом сообщение в своё адресно, клиент становится REPLY-блокированным в ожидания ответа. Если сервер после посылки клиентом сообщения не готов сразу его принять, клиент входит в SEND-блокированное состояние, и становится в очередь к серверу (возможно, с другими потоками-клиентами).

  1. Какой приоритет имеет посланное клиентом сообщение?


Если в момент вызова MsgReceive() в канале имеются сообщения, они принимаются сразу без блокирования сервера в порядке их приоритетов (поток сервера наследует приоритет потока, пославшего сообщение).

Или какое передадут при отправке.

  1. В чём отличие сигнала от импульса?


Импульс – это короткое неблокирующее сообщение фиксированной длины, посылаемое либо ядром операционной системы, либо пользовательскими потоками.

На импульс нельзя ответить, а на сигнал можно

Также есть сигналы, которые нельзя проигнорировать системе.

Сигналы нужны для завершения программы, значения сигналов предназначены для особых целей.

Каждый сигнал в системе имеет свой порядковый номер.

  1. В чём отличие сигналов реального времени от обычных сигналов?


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

  1. Какие функции библиотеки дают возможность назначить сигналу значение (value)?


sigwaitinfo — прием сигнала со значением

sigqueue — отправка

  1. В каких случаях для ожидания на сигнале используется функция sigsuspend()?


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

  1. Где находится информация о допустимости использования конкретной функции библиотеки в обработчике сигналов?


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

  1. Какие арифметические операции не рекомендуется выполнять в обработчике сигналов?


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

  1. Для каких целей используется функция sigaction()?


Задает обработчик сигнала

  1. Какой флаг и где используется для задания приёма очереди сигналов?


SA_SIGINFO

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


  • сигнала

  • импульса

  • сообщения

  • разблокирования потока



  1. Сколько таймеров можно создать в процессе?


Их количество ограничено только системными ресурсам.

  1. В чём разница между временны́ми базами CLOCK_REALTIME и CLOCK_MONOTONIC?


CLOCK_REALTIME — время с начала жпохи 1970 1

CLOCK_MONOTONIC — часы идущие с постоянной скоростью с момента загрузки ОС

  1. Какие преимущества имеют таймауты, задаваемые функциями, имеющими в имени подстроку “_timed”?


Признаком разблокирования по таймауту является возвращённая функциями ошибка ETIMEDOUT

+

это таймауты связанные с семафором или мьютексом

  1. На какие блокированные состояния можно установить таймаут с помощью функции timer_timeout()?


Устанавливает абсолютный или относительный таймаут в различных временных базах на блокированные состояния потоков. Уведомление об истечении таймаута задаётся структурой sigevent, т.е. если поток будет разблокирован по таймауту, будет сгенерировано событие, заданное в этой структуре, например, создание нового потока или посылка сигнала.

  1. Какие периодические таймеры способны отсчитывать время по часам CLOCK_MONOTONIC?


clock_*() (clock_gettext(), clock_nanosleep(), clock_settime(), ... ), в частности, разрешение каждого из базисов можно получить вызовом:

long sys_clock_getres( clockid_t which_clock, struct timespec *tp );

  1. Какое требование накладывает стандарт POSIX на время срабатывания одноразового таймера?


Это вещь из области POSIX — стандарт утверждает, что на различных платформах вы можете использовать различные типы временных базисов, но любая платформа должна, по меньшей мере, поддерживать базис CLOCK_REALTIME. В Neutrino есть три базиса: CLOCK_REALTIME; CLOCK_SOFTTIME; CLOCK_MONOTONIC
1   ...   6   7   8   9   10   11   12   13   14


написать администратору сайта