next up previous contents
Next: Структуры данных семафоров Up: Семафоры Previous: Семафоры   Contents

Основные сведения

Семафоры являются одним из классических примитивов синхронизации. Значение семафора - это целое число в диапазоне от 0 до 32767. Поскольку во многих приложениях требуется использование более одного семафора, ОС Linux предоставляет возможность создавать множества семафоров. Их максимальный размер ограничен системным параметром SEMMSL. Множества семафоров создаются при помощи системного вызова semget.

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

Над каждым семафором, принадлежащим некоторому множеству, при помощи системного вызова semop можно выполнить любую из трех операций:

Для выполнения первых двух операций у процесса должно быть право на изменение, для выполнения третьей достаточно права на чтение. Чтобы увеличить значение семафора, системному вызову semop следует передать требуемое число. Чтобы уменьшить значение семафора, нужно передать требуемое число, взятое с обратным знаком; если результат получается отрицательным, операция не может быть успешно выполнена. Для третьей операции нужно передать 0; если текущее значение семафора отлично от нуля, операция не может быть успешно выполнена.

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

При отсутствии флага IPC_NOWAIT системный вызов semop должен быть приостановлен до тех пор, пока значение семафора благодаря действиям другого процесса, не позволит успешно завершить операцию (ликвидация множества семафоров также приведет к завершению системного вызова). Подобные операции называются ''операциями с блокировкой''. С другой стороны, если обработка завершается неудачей и не указано, что выполнение процесса должно быть приостановлено, операция над семафором называется ``операцией без блокировки''.

Системный вызов semop оперирует не с отдельным семафором, а со множеством семафоров, применяя к нему ``массив операций''. Массив содержит информацию о том, с какими семафорами нужно оперировать и каким образом. Выполнение массива операций с точки зрения пользовательского процесса является неделимым действием. Это значит, во-первых, что если операции выполняются, то только все вместе и, во-вторых, что другой процесс не может получить доступа к промежуточному состоянию множества семафоров, когда часть операций из массива уже выполнена, а другая часть еще не начиналась.

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



2004-06-22