Семафоры.
Операционные системы
Условная операция типа Р, сокращенно CP (Conditional Р), уменьшающая значение семафора и возвращающая логическое значение «истина» в том случае, когда значение семафора остается положительным. Если в результате операции значение семафора должно стать отрицательным или нулевым, то никаких действий над ним не производится и операция возвращает логическое значение «ложь». Ядро выполняет операции… Читать ещё >
Семафоры. Операционные системы (реферат, курсовая, диплом, контрольная)
Семафоры Дейкстры представляют собой целочисленную переменную, обрабатываемую ядром с помощью некоторых элементарных операций, с которой связана очередь ожидающих процессов[1][2]. Над семафором можно выполнить только две операции — «поднятия» и «опускания», которые поименованы как Ри V-операции соответственно. Для получения процессом некоторого ресурса производится попытка уменьшить значение переменной на 1. Если ее значение > 1, то процесс получает ресурс. В противном случае (семафор закрыт) процесс приостанавливается и ставится в очередь. Процесс, закрывший семафор, захватывает ресурс. При освобождении ресурса процесс увеличивает значение семафора на единицу, открывая его.
Как правило, для реализации механизма семафоров используется алгоритм Деккера[1], в котором определены следующие элементарные операции:
- • инициализация семафора, в результате которой семафору присваивается неотрицательное значение;
- • операция типа Р, уменьшающая значение семафора. Если значение семафора опускается ниже нулевой отметки, то выполняющий операцию процесс приостанавливает свою работу;
- • операция типа V, увеличивающая значение семафора. Если значение семафора в результате операции становится больше или равно нулю, то один из процессов, приостановленных во время выполнения операции Р, выходит из состояния приостановки;
- • условная операция типа Р, сокращенно CP (Conditional Р), уменьшающая значение семафора и возвращающая логическое значение «истина» в том случае, когда значение семафора остается положительным. Если в результате операции значение семафора должно стать отрицательным или нулевым, то никаких действий над ним не производится и операция возвращает логическое значение «ложь».
Операции над семафорами обеспечивают синхронизацию выполнения процессов, работающих параллельно, выполняя набор действий над единой группой семафоров (средствами низкого уровня).
Поскольку операции элементарные, в любой момент времени для каждого семафора выполняется не более одной операции Р или V. Системные функции, осуществляющие операции над семафорами, выполняют групповые операции, т. е. в каждом вызове такой функции допускается одновременное выполнение нескольких операций. Однако опасность в выполнении функций над семафорами возникает при использовании мультипроцессорных систем.
Ядро выполняет операции комплексно; ни один из посторонних процессов не сможет переустанавливать значения семафоров, пока все операции не будут выполнены. Если ядро по каким-либо причинам не может выполнить все операции, то оно не выполняет ни одной; процесс приостанавливает свою работу до тех пор, пока эта возможность не будет предоставлена.
Итак, семафор — неотрицательная целая переменная, которая может изменяться и проверяться только посредством двух функций, как показано на следующем низкоуровневом фрагменте кода:
// Р — функция запроса семафора void P (s).
{
if (s==0)
//заблокировать текущий процесс else s = s-1;
}
// V — функция освобождения семафора void F (s).
{
if (s== 0)
//разблокировать один из заблокированных процессов s-s+1;
Семафоры, начиная с версии V системы UNIX, состоят из следующих элементов:
- • значения семафора;
- • идентификатора последнего из процессов, работавших с семафором;
- • количества процессов, ожидающих увеличения значения семафора;
- • количества процессов, ожидающих момента, когда значение семафора станет равным нулю.
Для создания набора семафоров и получения прав доступа к ним используется системная функция semget ()y для выполнения различных управляющих операций над набором — функция semctl ()y для работы со значениями семафоров — функция semop ().
Системный вызов semgetQ используется для того, чтобы создать новое множество семафоров или получить доступ к уже существующему. Вызов имеет синтаксис:
int semget (keyjt key, int nsemsy int semflg);
Функция возвращает IPC-идентификатор множества семафоров в случае успеха и -1 в случае ошибки. Кроме того, возвращается код ошибки через функцию егто (). Первый аргумент semget () — это ключ. Он сравнивается с ключами остальных множеств семафоров, присутствующих в системе. Вместе с тем решается вопрос о выборе между созданием и подключением к множеству семафоров в зависимости от аргумента nisgflg. В результате выполнения функции ядро выделяет запись, указывающую на массив семафоров и содержащую счетчик nsems. В записи также хранятся количество семафоров в массиве и время последнего выполнения функций semopQ и semcllQ.
Приведем пример простейшей функции для открытия и создания множества семафоров:
int open semaphore_set (keyl keyval, int numsems).
{.
int sid;
if {?numsems) retum{-1);
if {{sid = semget{ mykey, numsems, IPCCREAT 0660))==-/).
{.
retum{-iy,
}.
retum{sid);
}.
Синтаксис вызова системной функции semopQ: int semop{ int semid, struct sembuf * sops, unsigned nsops);
Функция возвращает 0 в случае успеха и -1 в случае ошибки. Первый аргумент вызова есть значение ключа {semget). Второй аргумент {sops) — указатель на массив операций, выполняемых над семафорами, третий аргумент — {nsops) является количеством операций в этом массиве. Аргумент sops указывает на массив типа sembuf. Эта структура описана в следующим образом:
struct sembuf
{.
ushort sem пит; /* semaphore index in array */ short semop; /* semaphore operation */ short sem Jig) /* operation flags */
}.
где semnum — номер семафора, с которым вы собираетесь работать; sem_ op — выполняемая операция (положительное, отрицательное число или нуль); sem Jig — флаги операции.
Если возвращаемое значение sem op отрицательно, то его значение вычитается из семафора. Это соответствует получению ресурсов, которые контролирует семафор.
Системный вызов semctlf) выполняет операции, управляющие множеством семафоров, имеет вид:
int semctl {int semid, int semnum, int cmd, union semun arg);
и возвращает натуральное число в случае успеха и -1 в случае ошибки. Этот вызов аналогичен вызову msgctlf) для очередей сообщений.