Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

ПРИМЕЧАНИЕ. ■ Очереди сообщений Posix (Posix message queues — глава 5) были добавлены в стандарт Posix (1003.1b-1993



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

■ Очереди сообщений Posix (Posix message queues — глава 5) были добавлены в стандарт Posix (1003.1b-1993, о котором более подробно рассказано в разделе 1.7). Они могут использоваться для взаимодействия родственных и неродственных процессов на каком-либо узле.

■ Удаленный вызов процедур (remote procedure calls — RPC, часть 5) появился в 80-х в качестве средства для вызова функций на одной системе (сервере) программой, выполняемой на другой системе (клиенте). Это средство было разработано в качестве альтернативы для упрощения сетевого программирования. Поскольку между клиентом и сервером обычно передается информация (передаются аргументы для вызова функции и возвращаемые значения) и поскольку удаленный вызов процедур может использоваться между клиентом и сервером на одном узле, RPC можно также считать одной из форм передачи сообщений.

Интересно также взглянуть на эволюцию различных форм синхронизации в процессе развития Unix:

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

■ Возможность блокирования записей (record locking — глава 9) была добавлена к ядрам Unix в начале 80-х и стандартизована в версии Posix.1 в 1988.

■ Семафоры System V (System V semaphores — глава 11) были добавлены вместе с возможностью совместного использования памяти (System V shared memory — глава 14) и одновременно с очередями сообщений System V (начало 80-х). Эти IPC поддерживаются большинством современных версий Unix.

■ Семафоры Posix (Posix semaphores — глава 10) и разделяемая память Posix (Posix shared memory— глава 13) были также добавлены в стандарт Posix (1003.1b-1993, который ранее упоминался в связи с очередями сообщений Posix).

■ Взаимные исключения и условные переменные (mutex, conditional variable — глава 7) представляют собой две формы синхронизации, определенные стандартом программных потоков Posix (Posix threads, Pthreads — 1003.1с-1995). Хотя обычно они используются для синхронизации между потоками, их можно применять и при организации взаимодействия процессов.

■ Блокировки чтения-записи (read-write locks — глава 8) представляют собой дополнительную форму синхронизации. Она еще не включена в стандарт Posix, но, вероятно, скоро будет.

Билет 19.

1)Системные вызовы для работы с таймером.

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

#include <time.h> void main(){ struct timeval timenow; gettimeofday (& timenow, NULL); printf("%u sec, %u msec\n", timenow.tv_sec, timenow.tv_usec); printf("%s", ctime (&timenow.tv_sec)); exit(0); }

Поле tv _ sec содержит число секунд, прошедшее с полуночи 1 января 1970 года до данного момента; в чем полностью соответствует системному вызову time. Однако плюс к тому поле tv _ usec содержит число миллионных долей текущей секунды (значение этого поля всегда меньше 1000000).

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

struct tms { clock_t tms _ utime; clock_t tms _ stime; clock_t tms _ cutime; clock_t tms _ cstime; };

и возвращает значение

#include <sys/times.h> struct tms time _ buf; clock_t real _ time = times (& time _ buf);

Все времена измеряются в "тиках" - некоторых долях секунды. Число тиков в секунде можно узнать таким системным вызовом (в системе Solaris):

#include <unistd.h> clock_t HZ = sysconf (_SC_CLK_TCK);

В старых системах, где таймер работал от сети переменного тока, это число получалось равным 60 (60 Герц - частота сети переменного тока). В современных системах это 100. Поля структуры содержат:

tms _ utime

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

tms _ stime

время, затраченное вызывающим процессом в системной фазе.

tms _ cutime

время, затраченное порожденными процессами в пользовательской фазе: оно равно сумме всех tms _ utime и tms _ cutime порожденных процессов (рекурсивное суммирование).

tms _ cstime

время, затраченное порожденными процессами в системной фазе: оно равно сумме всех tms _ stime и tms _ cstime порожденных процессов (рекурсивное суммирование).

real _ time

время, соответствующее астрономическому времени системы. Имеет смысл мерять только их разность.


2) Сигналы в UNIX, Unix-подобных и других POSIX-совместимых операционных системах являются одним из способов взаимодействия между процессами (англ. IPC, inter-process communication). Фактически, сигнал — это асинхронное уведомление процесса о каком-либо событии. Когда сигнал послан процессу, операционная система прерывает выполнение процесса. Если процесс установил собственный обработчик сигнала, операционная система запускает этот обработчик, передав ему информацию о сигнале. Если процесс не установил обработчик, то выполняется обработчик по умолчанию.

Названия сигналов «SIG…» являются числовыми константами (макроопределениями Си) со значениями, определяемыми в заголовочном файле signal.h. Числовые значения сигналов могут меняться от системы к системе, хотя основная их часть имеет в разных системах одни и те же значения. Утилита kill позволяет задавать сигнал как числом, так и символьным обозначением.

Одним из способов взаимодействия процессов в unix системах являются сигналы. Это способ передачи информации о возникшем событии от одного процесса другому. С помощью сигналов может быть прервано нормальное выполнение процесса. Например, в случае, когда пользователь нажимает на клавиатуре клавиши прерывания, такие как “Del”, “CTRL + C”, то текущему процессу посылается соответствующий сигнал. При получении такого сигнала процесс будет прерван. Либо, если процесс производит деление на ноль, то в этом случае сигнал для прерывания посылает ядро.
В ранних версиях unix систем, реализация сигналов не была надежной, сигналы могли теряться. И в разных версиях модели сигналов различались. Впоследствии модели сигналов стали достаточно надежными и стандартизированы. Они описаны в стандарте POSIX.1. Каждый сигнал имеет уникальное символьное имя и соответствующий номер. В современных системах существует несколько десятков сигналов.
Сигнал может быть послан либо ядром, либо другим процессом, причем, если процесс запущен от имени непривилегированного пользователя, то такой процесс может послать сигнал только процессам этого же пользователя. Процессы от пользователя root могут посылать сигналы любым процессам. Отправка сигнала происходит с помощью системного вызова kill. В качестве параметров передается номер или имя сигнала и PID процесса, которому посылается сигнал. Причины, из-за которых возникает необходимость отправить сигнал, могут быть следующими: ядро отправляет соответствующий сигнал процессу, если пользователь нажал определенные клавиши, или комбинацию клавиш. Либо особые аппаратные ситуации: деление на ноль, обращение к недопустимой области памяти и т.д., либо особые программные ситуации: срабатывание запрограммированного таймера.
У процесса, получившего сигнал, есть несколько вариантов реакции. Он может выбрать одно из трех действий:

· Игнорировать сигнал

· Перехватить и обработать самостоятельно

· Позволить действие по умолчанию

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

· HUP(1) – Этот сигнал обычно посылается процессам, для которых ядром обнаруживается, что терминал, к которому привязаны эти процессы, отсоединился (потеря линии). Либо все процессам одной сессии, когда завершает работу родитель всех процессов данной сессии. Этот сигнал используется ещё для процессов демонов. Они не привязаны к терминалу, поэтому они просто перечитывают свои конфигурационные файлы. Так работают такие процессы, как squid, apache. Сигнал можно перехватить и блокировать, дамп с образом памяти процесса не создается.

· INT(2) – Сигнал посылается ядром текущему процессу, при нажатии клавиш "DEL" или “CTRL+C”. Происходит завершение работы. Сигнал можно перехватить и блокировать, дамп с образом памяти процесса не создается.

· QUIT(3) – Посылается процессам при нажатии “CTRL+\”. Происходит завершение работы. Сигнал можно перехватить и блокировать, создается дамп с образом памяти процесса.

· KILL(9) – При получении этого сигнала, происходит завершение процесса, корме нескольких случаев, которые рассмотрим в следующей статье. Этот сигнал нельзя ни перехватить, ни блокировать. Дамп с образом памяти процесса не создается.

· TERM(15) – Сигнал – предупреждение, что процесс скоро будет уничтожен. Позволяет процессу удалить временные файлы, завершить транзакции. Это значение используется по умолчанию, если в команде не задан сигнал. Сигнал можно перехватить и блокировать, дамп с образом памяти процесса не создается.

· STOP(17,19,23) – Сигнал отправляется при нажатии комбинации клавиш “CTRL+Z”. Вызывает rootостановку процесса. Процесс перестает выполняться, но не завершается. Этот сигнал нельзя ни перехватить, ни блокировать. Дамп с образом памяти процесса не создается. Значения приведены для Fedora. В других версиях могут иметь другие значения.

2)организация сигналов в процессах

Одним из способов взаимодействия процессов в unix системах являются сигналы. Это способ передачи информации о возникшем событии от одного процесса другому. С помощью сигналов может быть прервано нормальное выполнение процесса. Например, в случае, когда пользователь нажимает на клавиатуре клавиши прерывания, такие как “Del”, “CTRL + C”, то текущему процессу посылается соответствующий сигнал. При получении такого сигнала процесс будет прерван. Либо, если процесс производит деление на ноль, то в этом случае сигнал для прерывания посылает ядро.
В ранних версиях unix систем, реализация сигналов не была надежной, сигналы могли теряться. И в разных версиях модели сигналов различались. Впоследствии модели сигналов стали достаточно надежными и стандартизированы. Они описаны в стандарте POSIX.1. Каждый сигнал имеет уникальное символьное имя и соответствующий номер. В современных системах существует несколько десятков сигналов.
Сигнал может быть послан либо ядром, либо другим процессом, причем, если процесс запущен от имени непривилегированного пользователя, то такой процесс может послать сигнал только процессам этого же пользователя. Процессы от пользователя root могут посылать сигналы любым процессам. Отправка сигнала происходит с помощью системного вызова kill. В качестве параметров передается номер или имя сигнала и PID процесса, которому посылается сигнал. Причины, из-за которых возникает необходимость отправить сигнал, могут быть следующими: ядро отправляет соответствующий сигнал процессу, если пользователь нажал определенные клавиши, или комбинацию клавиш. Либо особые аппаратные ситуации: деление на ноль, обращение к недопустимой области памяти и т.д., либо особые программные ситуации: срабатывание запрограммированного таймера.
У процесса, получившего сигнал, есть несколько вариантов реакции. Он может выбрать одно из трех действий:

· Игнорировать сигнал

· Перехватить и обработать самостоятельно

· Позволить действие по умолчанию

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

· HUP(1) – Этот сигнал обычно посылается процессам, для которых ядром обнаруживается, что терминал, к которому привязаны эти процессы, отсоединился (потеря линии). Либо все процессам одной сессии, когда завершает работу родитель всех процессов данной сессии. Этот сигнал используется ещё для процессов демонов. Они не привязаны к терминалу, поэтому они просто перечитывают свои конфигурационные файлы. Так работают такие процессы, как squid, apache. Сигнал можно перехватить и блокировать, дамп с образом памяти процесса не создается.

· INT(2) – Сигнал посылается ядром текущему процессу, при нажатии клавиш "DEL" или “CTRL+C”. Происходит завершение работы. Сигнал можно перехватить и блокировать, дамп с образом памяти процесса не создается.

· QUIT(3) – Посылается процессам при нажатии “CTRL+\”. Происходит завершение работы. Сигнал можно перехватить и блокировать, создается дамп с образом памяти процесса.

· KILL(9) – При получении этого сигнала, происходит завершение процесса, корме нескольких случаев, которые рассмотрим в следующей статье. Этот сигнал нельзя ни перехватить, ни блокировать. Дамп с образом памяти процесса не создается.

· TERM(15) – Сигнал – предупреждение, что процесс скоро будет уничтожен. Позволяет процессу удалить временные файлы, завершить транзакции. Это значение используется по умолчанию, если в команде не задан сигнал. Сигнал можно перехватить и блокировать, дамп с образом памяти процесса не создается.

· STOP(17,19,23) – Сигнал отправляется при нажатии комбинации клавиш “CTRL+Z”. Вызывает rootостановку процесса. Процесс перестает выполняться, но не завершается. Этот сигнал нельзя ни перехватить, ни блокировать. Дамп с образом памяти процесса не создается. Значения приведены для Fedora. В других версиях могут иметь другие значения.

Билет 20.

1)виртуальное адресное пространство процесса

В 32-битных системах процессор может сгенерировать 32-битный адрес. Это означает, что каждому процессу выделяется диапазон виртуальных адресов от 0x00000000 до 0xFFFFFFFF. Эти 4 Гб адресов система делит примерно пополам, и для кода и данных пользовательского режима отводятся 2 Гб в нижней части памяти. Если быть более точным, то речь идет об виртуальных адресах, начиная с 0x00010000 и кончая 07FFEFFFF (см. [6]). Таким образом, система управления памятью позволяет пользовательской программе с помощью Win32 API записать нужный байт в любую виртуальную ячейку из этого диапазона адресов. Адреса верхней части виртуальной памяти используется для кода и данных режима ядра и других системных нужд.По умолчанию адресное пространство каждого процесса изолировано. Данные двух разных процессов, записанные по одному и тому же виртуальному адресу, оказываются в разных страницах физической памяти при помощи корректной работы системы трансляции адреса. В ряде случаев изоляция может быть частично снята (файлы, отображаемые в память; разделяемая память). Разумеется, в подобных случаях нужно отдельно обеспечить контроль доступа к области памяти, для чего создается отдельный объект (объект-секция или объект-раздел, section object), включающий атрибуты защиты. Ниже будет также приведен пример контроля процессом памяти другого процесса - прием, которым активно пользуются отладчики.





Дата публикования: 2015-01-24; Прочитано: 170 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.009 с)...