Скачать презентацию
Идет загрузка презентации. Пожалуйста, подождите
Презентация была опубликована 11 лет назад пользователемweb-local.rudn.ru
1 1 Архитектура вычислительных систем. Лекция 8. Ловецкий К.П. Москва, декабрь 2012 Управление свойствами процесса
2 Wedge Paradox 2 Contributed by Carsten Kolve
3 3 Текущий и корневой каталоги Текущий каталог можно сменить с помощью вызова int chdir(const char* path); подав в качестве параметра полный путь нового каталога либо путь относительно текущего каталога. Строка ".." означает каталог уровнем выше относительно заданного (например, /usr/local/share/.. это то же самое, что /usr/local). Смена корневого каталога осуществляется вызовом int chroot(const char* path); После выполнения этого вызова каталоги за пределом нового корневого перестают быть видны или каким-либо образом доступны процессу и всем его потомкам. Операция смены корневого каталога необратима. Вызов chroot() могут выполнять только процессы, имеющие права пользователя root.
4 4 Окружение процесса Окружение доступно в программах на C через глобальную переменную extern char **environ; Для манипуляции переменными окружения служат функции char *getenv(const char *name); int setenv(const char *name, const char *value, int overwrite); void unsetenv(const char *name); Функция getenv() возвращает строку, являющуюся значением переменной, имя которой задается аргументом name. Если такой переменной в окружении нет, возвращается значение NULL. Функция setenv() устанавливает новое значение переменной, причем если такой переменной не было, значение устанавливается в любом случае, если же соответствующая переменная в окружении уже есть, новое значение устанавливается только при ненулевом значении параметра overwrite; таким образом, параметр overwrite разрешает или запрещает изменять значение переменной окружения, если таковая уже есть. Функция unsetenv() удаляет переменную с заданным именем из окружения.
5 5 Пример программы, которая выводит значения аргументов, переданных параметров и переменных окружения argv[1] = first argv[2] = second argv[3] = 3 environ[0] LOGNAME=andy environ[1] MAIL=/var/mail/andy environ[2] LD_LIBRARY_PATH=/usr/openwin/lib;/usr/ucblib environ[3] PAGER=/usr/bin/pg environ[4] TERM=vtlOO environ[5] PATH=/usr/bin;/bin;/usr/sbin;/sbin;/usr/css environ[6] HOME=/home/andy environ[7] SHELL=/usr/local/bin/bash #include extern char **environ; main (int argc, char *argv[]) {Int I; printf(число параметров %s равно %d/n, argv[0], argc-1); for (i=1; i
6 6 Параметр umask Параметр umask (код доступа, определяется маской ) можно изменить с помощью системного вызова int umask(int mask); Этот вызов всегда завершается успешно и возвращает предыдущее значение параметра umask. Манипуляция таблицей дескрипторов Новые файловые дескрипторы создаются при успешном выполнении вызова open(), а также во многих других случаях. При создании нового файлового дескриптора система всегда выбирает наименьший свободный номер; так, если закрыть нулевой дескриптор, следующий успешный вызов open() вернет ноль.
7 7 Манипуляция таблицей дескрипторов Для закрытия дескриптора используется уже рассматривавшийся вызов close(). Кроме этого, очень важны еще два системных вызова, создающие синонимы существующих дескрипторов: int dup(int fd); int dup2(int fd, int new_fd); Вызов dup() создает новый файловый дескриптор, связанный с тем же самым потоком ввода-вывода, что и fd. Новый и старый дескрипторы разделяют, в числе прочего, и указатель текущей позиции в файле: если на одном из них сменить позицию с помощью lseek(), позиция на втором из них также изменится. Вызов dup2() отличается тем, что новый дескриптор создается под заданным номером (параметр new_fd). Если этот номер был связан с открытым дескриптором, тот дескриптор закрывается.
8 8 Управление прочими свойствами процесса Узнать значения параметров uid, gid, euid, egid, pid, ppid, sid и pgid можно, соответственно, системными вызовами getuid(), getgid() и т.д. Параметры pid, ppid (идентификатор процесса и его предка) изменить нельзя. Манипуляция параметрами sid и pgid будет рассмотрена в нашем курсе позже, на лекции, посвященной сеансам и группам процессов. Параметры uid, gid, euid, egid, идентифицирующие полномочия про- цесса, в некоторых случаях могут быть изменены. Об этом речь пойдет при рассмотрении полномочий процессов. Наконец, обработка сигналов будет рассмотрена при изучении сигналов как средства межпроцессного взаимодействия.
9 9 Общая классификация средств взаимодействия процессов в ОС Unix
10 10 Общая классификация средств взаимодействия процессов в ОС Unix В рамках одной Unix-системы процессы могут так или иначе взаимодействовать между собой. Вообще говоря, один процесс может повлиять на работу другого, не прибегая к специализированным средствам; например, процесс может модифицировать файл, читаемый другим процессом. Тем не менее, для организации взаимодействия процессов удобней пользоваться средствами, которые для этого специально предназначены. Наиболее примитивным из таких средств являются сигналы. Сигнал не несет в себе никакой информации, кроме номера сигнала целого числа из предопределенного множества.
11 11 Общая классификация средств взаимодействия процессов в ОС Unix Для передачи данных между процессами можно использовать однонаправленные каналы, различающиеся на именованные и неименованные. Системный вызов mmap() позволяет создать область памяти, доступную нескольким процессам. Такая область памяти называется разделяемой, а процессы, работающие с ней, считаются взаимодействующими через разделяемую память. При отладке программ используется режим трассировки, при которой один процесс (обычно отладчик) контролирует выполнение другого (отлаживаемой программы). Важную роль в системах семейства Unix играет понятие терминала. При необходимости, функциональность терминала как устройства может имитировать пользовательский процесс (так работает, например, программа xterm, а также серверы, отвечающие за удаленный доступ к машине, такие как sshd или telnetd). Взаимодействие такого процесса с процессами, для которых имитируемый (то есть программно реализованный) терминал является управляющим, называется взаимодействием через виртуальный терминал.
12 12 Общая классификация средств взаимодействия процессов в ОС Unix Основным средством взаимодействия через компьютерную сеть (то есть взаимодействия процессов, находящихся в разных системах), являются сокеты (sockets). Сокеты представляют собой универсальный механизм, пригодный для работы с широким спектром протоколов; это означает, что область применения сокетов не ограничена сетями на основе TCP/IP или какого-либо другого стандарта; более того, при добавлении в систему поддержки новых протоколов нет необходимости изменять интерфейсы системных вызовов. Реализация сокетов в ОС Unix поддерживает также специальный вид протокола, который можно использовать внутри одной системы, даже если поддержка компьютерных сетей в системе отсутствует.
13 13 Сигналы Один из простейших способов повлиять на работу процесса это отправить ему сигнал из некоторого предопределенного множества. Изначально сигналы были предназначены для снятия процессов с выполнения, но с развитием системы приобрели другие функции. Перечислим некоторые наиболее употребительные сигналы: SIGTERM предписывает процессу завершиться. Процесс может перехватить или игнорировать этот сигнал. SIGKILL уничтожает процесс. В отличие от SIGTERM, этот сигнал ни перехватить, ни игнорировать нельзя. Разделение «уничтожающих» сигналов на перехватываемый и неперехватываемый введено с целью создания более гибкой процедуры снятия процессов. Так, при перезагрузке системы всем процессам рассылается сначала SIGTERM, а затем, через 5 секунд SIGKILL. Это позволяет процессам «привести свои дела в порядок»: например, редактор текстов может сохранить несохраненный редактируемый текст во временном файле с тем, чтобы потом (в начале следующего сеанса редактирования) предложить пользователю восстановить несохраненные им изменения. Предназначение некоторых сигналов
14 14 Сигналы SIGILL, SIGSEGV, SIGFPE и SIGBUS система отправляет процессам, чьи действия привели к возникновению программного прерывания (соответственно, попытка выполнить несуществующую или недопустимую команду процессора, нарушение защиты памяти, деление на ноль и обращение к памяти по некорректному адресу). По умолчанию любой из этих сигналов уничтожает процесс с созданием core-файла для последующего анализа причин происшествия. Однако любой из этих сигналов можно перехватить (например, чтобы попытаться перед завершением записать в файл результаты работы). SIGSTOP и SIGCONT позволяют, соответственно, приостановить и продолжить выполнение процесса. Отметим, что SIGSTOP, как и SIGKILL, нельзя ни перехватить, ни игнорировать. SIGCONT перехватить можно, но свою основную функцию (продолжить выполнение процесса) он выполняет в любом случае. Предназначение некоторых сигналов
15 15 Сигналы SIGINT и SIGQUIT отправляются основной группе процессов данного терминала при нажатии на клавиатуре комбинаций Ctrl+C и Ctrl-\, соответственно. По умолчанию оба сигнала приводят к завершению процесса, причем SIGQUIT еще и создает core-файл. SIGCHLD система присылает родительскому процессу при завершении дочернего. SIGALRM присылается по истечении заданного интервала времени после вызова alarm(). Таким образом процесс может взвести для себя «напоминание», например, на случай чрезмерно долгого выполнения тех или иных действий. Отправителем этого сигнала обычно является операционная система. SIGUSR1 и SIGUSR2 предназначены для использования программистом для своих целей. Отметим, что по умолчанию эти сигналы также завершают процесс. Предназначение некоторых сигналов
16 16 Отправка сигнала Отправителем сигнала может быть как процесс, так и операционная система, получателем всегда процесс. Для отправки сигнала служит системный вызов int kill(int target_pid, int sig_no); Параметр sig_no задает номер подлежащего отправке сигнала. Для лучшей ясности программы рекомендуется использовать вместо чисел макро-константы с префиксом SIG, такие как SIGINT, SIGUSR1 и т.п. Параметр target_pid задает процесс(ы) которому (которым) следует отправить сигнал. Если в качестве этого параметра передать положительное число, это число будет использоваться как номер процесса, которому следует послать сигнал. Если передать число -1, сигнал будет послан всем процессам, кроме самого вызвавшего kill(). Отрицательное число, большее единицы по модулю, означает передачу сигнала группе процессов с соответствующим номером. Ноль означает передачу сигнала всем процессам своей группы. Процессы, имеющие полномочия суперпользователя (uid == 0), могут отправлять сигналы любым процессам; все прочие процессы имеют право отправки сигнала только процессам, принадлежащим тому же пользователю.
17 17 Обработка сигналов Если не предпринять специальных мер, большинство сигналов завершают процесс, причем некоторые из них еще и создают core- файл, содержащий сегмент данных и стека завершенного процесса. Некоторые сигналы (например, SIGCHLD) по умолчанию игнорируются. Процесс может для любого сигнала, кроме SIGKILL и SIGSTOP, установить свой режим обработки: вызов функции-обработчика, игнорирование или обработка по умолчанию. Функция-обработчик должна принимать один целочисленный параметр и иметь тип возвращаемого значения void, т.е. это должна быть функция вида void handler(int s) { /*... */ }
18 18 Обработка сигналов Для установки обработчика сигнала можно использовать системный вызов signal(): typedef void (*sighandler_t)(int); sighandler_t signal(int signo, sighandler_t hdl); Параметр signo задает номер сигнала, параметр hdl адрес функции, которая должна быть вызвана при получении соответствующего сигнала. В качестве значения hdl также можно использовать специальные значения SIG_IGN (игнорировать сигнал) и SIG_DFL (установить обработку по умолчанию). Вызов signal() возвращает значение, соответствующее предыдущему режиму обработки для данного сигнала, либо SIG_ERR в случае ошибки. После установки функции-обработчика в случае, если кто-либо отправит нашему процессу сигнал, будет вызвана функция- обработчик (с параметром, равным номеру сигнала).
19 19 Системный вызов alarm() С помощью вызова alarm() можно затребовать от ядра отправки нашему процессу сигнала SIGALRM через определенное количество секунд реального времени. Прототип вызова таков: int alarm(unsigned int seconds); Параметр задает количество секунд, через которое следует прислать сигнал. Каждому процессу в системе может соответствовать один активный заказ на отправку SIGALRM; когда заказанный период времени истекает, система присылает процессу сигнал, а сам активный заказ уничтожается. Возвращаемое вызовом alarm() значение зависит от того, имеется ли уже для данного процесса активный заказ на отправку SIGALRM. Если такого не было, вызов возвращает ноль. Если же активный заказ уже был, возвращено будет количество секунд, оставшееся до момента его исполнения.
20 20 Каналы Канал это объект ядра, представляющий собой средство однонаправленной передачи данных. Канал всегда имеет два конца, один для записи, другой для чтения. С каждым концом канала могут быть связаны файловые дескрипторы, принадлежащие, возможно, разным процессам.
21 21 Неименованные каналы Неименованный канал создается системным вызовом int pipe(int fd[2]); На вход ему подается адрес массива из двух элементов типа int; в этот массив вызов pipe() записывает дескрипторы, связанные с созданным каналом: fd[0] для чтения, fd[1] для записи. Как ясно из названия, такой канал не имеет имени и, соответственно, не существует способа подключиться к такому каналу из другого процесса. Единственный способ добиться того, чтобы к одному и тому же каналу оказались подключены разные процессы это создать копию процесса, создавшего канал, с помощью вызова fork(). Таким образом, использовать неименованный канал для взаимодействия между собой могут только родственные процессы, чей общий предок создал соответствующий канал.
22 22 Неименованные каналы Показано связывание с помощью неименованного канала двух дочерних процессов. На первом шаге родительский процесс создает канал. Затем родительский процесс порождает два дочерних процесса, в результате чего во всех трех процессах оказываются дескрипторы как одного, так и второго концов канала. После этого родительский процесс закрывает свои экземпляры дескрипторов, чтобы не мешать дочерним процессам использовать канал. В свою очередь, в первом дочернем процессе закрывается дескриптор, предназначенный для чтения, во втором для записи. В результате дочерние процессы оказываются связаны таким образом, что первый второму может передавать данные через канал.
23 23 Именованные каналы (FIFO) Именованные каналы по сути своей подобны неименованным, с той разницей, что именованному каналу соответствует файл специального типа (FIFO), размещаемый в файловой системе. Таким образом, к именованному каналу могут присоединяться процессы, не имеющие родственных связей; более того, закрытие всех дескрипторов, отвечающих за чтение из такого канала или за запись в такой канал еще не означает, что канал более не пригоден для работы, т.к. в любой момент такие дескрипторы могут появиться вновь. Для создания файла FIFO используется функция int mkfifo(const char *pathname, int permissions); Первый параметр задает имя файла, второй права доступа к нему (аналогично вызовам open() и mkdir()). Права, естественно, модифицируются параметром umask. Функция возвращает -1 в случае ошибки, 0 в случае успеха.
24 24 Именованные каналы (FIFO) При создании файла FIFO система не создает сам объект канала; это происходит только тогда, когда какой-либо процесс открывает файл FIFO с помощью вызова open() на чтение или запись, причем объект канала продолжает существовать до тех пор, пока существует хотя бы один связанный с ним дескриптор, после чего уничтожается. Уничтожение объекта канала не означает уничтожения файла FIFO: после закрытия всех дескрипторов файл остается на месте и может быть снова открыт каким-либо процессом, после чего объект канала снова появится.
25 25 Th-th-th-that's all folks!
Еще похожие презентации в нашем архиве:
© 2024 MyShared Inc.
All rights reserved.