Операции над семафорами: вызов semop

Вызов semop выполняет основные операции над семафорами.

Описание

#include <sys/sem.h>

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

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

И снова основной акцент делается на операции с наборами семафоров, при этом функция semop позволяет выполнять группу операций как атомарную опе­рацию. Это означает, что пока не появится возможность одновременного выпол­нения всех операций с отдельными семафорами набора, не будет выполнена ни одна из этих операций. Если не указано обратного, процесс приостановит работу дотех пор, пока он не сможет выполнить все операции сразу.

Рассмотрим структуру sembuf. Она включает в себя следующие элементы: unsigned short sem_num;

short sem_op;

short sem_flg;

Поле sem_num содержит индекс семафора в наборе. Если, например, набор со­держит всего один элемент, то значение sem_num должно быть равно нулю. Поле 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_f lg установлен флаг IPC_NOWAIT, то возврат из вызова sem_op произойдет немедленно, и переменная errno будет содержать код ошибки EAGAIN.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: