Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
мои шпоры ОСиСП(1).doc
Скачиваний:
34
Добавлен:
26.09.2019
Размер:
1.63 Mб
Скачать

Int semop(int semid, struct sembuf *op_array, size_t num_ops);

Переменная semid является идентификатором набора семафоров, полученным с помощью вызова semget. Параметр op_array является массивом струк­тур sembuf, определенных в файле <sys/sem.h>. Каждая структура sembuf со­держит описание операций, выполняемых над семафором.

Структура sembuf включает в себя следующие элементы:

unsigned short sem_num; // индекс семафора в наборе

short sem_op;

short sem_flg;

Поле sem_op содержит целое число со знаком, значение которого сообщает функции semop, что необходимо сделать. При этом возможны три случая:

1: отрицательное значение sem_op:

Это обобщенная форма команды для работы с семафорами p (), которая обсуждалась ранее. Действие функции semop можно описать при помощи псевдокода следующим образом (обратите внимание, что ABS() обозначает модуль пере­менной):

if( semval >= ABS(sem_op) )

{semval = semval - ABS(sem_op);}

else

{

if( (sem_flg & IPC_NOWAIT) )

немедленно вернуть -1

else

{

ждать, пока semval не станет больше или равно ABS(sem_op)

затем, как и выше, вычесть ABS(sem_op)

}

}

Основная идея заключается в том, что функция semop вначале проверяет значе­ние semval, связанное с семафором sem_num. Если значение semval достаточно ве­лико, то оно сразу уменьшается на указанную величину. В противном случае процесс будет ждать, пока значение semval не станет достаточно большим. Тем не менее, если в переменной sem_flg установлен флаг IPC_NOWAIT, то возврат из вызова sem_op произойдет немедленно, и переменная errno будет содержать код ошибки EAGAIN.

2: положительное значение sem_op

Это соответствует традиционной операции v (). Значение переменной sem_op просто прибавляется к соответствующему значению semval. Если есть процессы, ожидающие изменения значения этого семафора, то они могут продолжить вы­полнение, если новое значение семафора удовлетворит их условия.

3: нулевое значение sem_op

В этом случае вызов sem_op будет ждать, пока значение семафора не станет равным нулю; значение semval этим вызовом не будет изменяться. Если в пере­менной sem_flg установлен флаг IPC_NOWAIT, а значение semval еще не равно нулю, то функция semop сразу же вернет сообщение об ошибке.

2. Применение общего семафора для решения задачи "производитель-потребитель" с неограниченным буфером.

Рассматриваются два процесса, которые называются производитель и потребитель. Оба процесса являются циклическими. Производитель при каждом циклическом повторении участка программы про­изводит отдельную порцию информации, которая должна быть обработана потребителем. Потребитель при каждом повторении обрабатывает следующую порцию информации, выработанную производите­лем. Отношения производитель-потребитель подразумевают односторонний канал связи, по которому могут передаваться порции информации. С этой целью процессы связаны через буфер неограниченной емкости. То есть, произведенные порции не должны немедленно потребляться, а могут организовывать в буфере очередь. Буфер работает по принципу FIFO.

ЧПБ – число порций в буфере.

РБ – работа с буфером

begin integer ЧПБ;

ЧПБ := 0;

parbegin

производитель: begin

П1: производство новой порции;

добавление новой порции в буфер;

v(ЧПБ);

goto П1;

end;

потребитель: begin

П2: p(ЧПБ);

взятие порции из буфера;

обработка взятой порции;

goto П2;

end;

parend;

end;

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

begin integer ЧПБ, РБ;

ЧПБ := 0;

parbegin

производитель: begin П1: производство новой порции;

p(РБ)

добавление новой порции в буфер;

v(PБ);

v(ЧПБ);

goto П1;

end;

потребитель: begin П2: p(ЧПБ);

p(PБ);

взятие порции из буфера;

v(PБ);

обработка взятой порции;

goto П2;

end;

parend;

end;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]