Системные вызовы Unix/Linux
В ОС Unix/Linux механизм семафоров обслуживается тремя системными вызовами: semget, semctl и semop.
Системный вызов semget создает массив семафоров или возвращает идентификатор уже существующего массива семафоров. Этот идентификатор используется при дальнейших операциях с семафорами. Системные вызовы работают с массивами семафоров, это сделано только лишь для того, чтобы иметь общую идентификацию для всех семафоров одной задачи. Системные вызовы semctl и semop дают возможность отдельно оперировать с каждым семафором массива.
Системный вызов semctl позволяет выполнять управляющие операции над массивом семафоров и отдельными его элементами: читать и устанавливать значения, уничтожать массив семафоров.
Системный вызов semop выполняет прикладные семафорные операции: аналоги P- и V-операций, а также проверки состояния семафора.
Семафоры в Unix/Linux не имеют внешних имен. При получении идентификатора семафора процесс пользуется числовым ключом. Разработчики несвязанных процессов могут договориться об общем значении ключа, который они будут использовать, но у них нет гарантии в том, что это же значение ключа не будет использовано кем-то еще. Гарантированно уникальный массив семафоров можно создать с использованием ключа , но такой ключ не может быть внешним. Поэтому семафоры используются, как правило, родственными процессами, которые имеют возможность передавать друг другу идентификаторы семафоров, например, через наследуемые ресурсы или через параметры вызова дочерней программы. .
Семафор — средство управления процессами
Семафор — это защищенная переменная, значение которой можно опрашивать и менять только при помощи специальных операций wait и signal и операции инициализации init. Двоичные семафоры могут принимать только значения 0 и 1. Семафоры со счетчиками могут принимать неотрицательные целые значения.
Операция wait(s) над семафором s состоит в следующем:
если s > то s:=s-1 иначе (ожидать на s) а операция signal(s) заключается в том, что: если (имеются процессы, которые ожидают на s) то (разрешить одному из них продолжить работу) иначе s:=s+1
Операции являются неделимыми. Критические участки процессов обрамляются операциями wait(s) и signal(s). Если одновременно несколько процессов попытаются выполнить операцию wait(s), то это будет разрешено только одному из них, а остальным придется ждать.
Семафоры со счетчиками используются, если некоторые ресурс выделяется из множества идентичных ресурсов. При инициализации такого семафора в его счетчике указывается число элементов множества. Каждая операция wait(s) уменьшает значения счетчика семафора s на 1, показывая, что некоторому процессу выделен один ресурс из множества. Каждая операция signal(s) увеличивает значение счетчика на 1, показывая, что процесс возвратил ресурс во множество. Если операция wait(s) выполняется, когда в счетчике содержится нуль (больше нет ресурсов), то соответствующий процесс ожидает, пока во множество не будет возвращен освободившийся ресурс, то есть пока не будет выполнена операция signal. .
Пример
Есть некоторое число читателей, которые приходят в библиотеку три раза в день и что-то там читают. И пусть будет ограничение, что единовременно в библиотеке не может находиться больше трех читателей. Данную задачу очень легко решить с помощью семафоров:
using System; using System.Threading; namespace SemaphoreApp { class Program { static void Main(string[] args) { for (int i = 1; i < 6; i++) { Reader reader = new Reader(i); } Console.ReadLine(); } } class Reader { // создаем семафор static Semaphore sem = new Semaphore(3, 3); Thread myThread; int count = 3;// счетчик чтения public Reader(int i) { myThread = new Thread(Read); myThread.Name = "Читатель " + i.ToString(); myThread.Start(); } public void Read() { while (count > 0) { sem.WaitOne(); Console.WriteLine("{0} входит в библиотеку", Thread.CurrentThread.Name); Console.WriteLine("{0} читает", Thread.CurrentThread.Name); Thread.Sleep(1000); Console.WriteLine("{0} покидает библиотеку", Thread.CurrentThread.Name); sem.Release(); count--; Thread.Sleep(1000); } } } }
В данной программе читатель представлен классом Reader. Он инкапсулирует всю функциональность, связанную с потоками, через переменную .
Для создания семафора используется класс Semaphore: ;. Его конструктор принимает два параметра: первый указывает, какому числу объектов изначально будет доступен семафор, а второй параметр указывает, какой максимальное число объектов будет использовать данный семафор. В данном случае у нас только три читателя могут одновременно находиться в библиотеке, поэтому максимальное число равно 3.
Основной функционал сосредоточен в методе Read, который и выполняется в потоке. В начале для ожидания получения семафора используется метод . После того, как в семафоре освободится место, данный поток заполняет свободное место и начинает выполнять все дальнейшие действия. После окончания чтения мы высвобождаем семафор с помощью метода . После этого в семафоре освобождается одно место, которое заполняет другой поток.
А в методе Main остается только создать читателей, которые запускают соответствующие потоки.
Также, достаточно интересно представлен принцип работы семафора в публикации с сайта «ITnan» . .
Определения
Светофор – оптическое устройство, регулирующее движение пешеходов и транспортных средств (автомобилей, поездов, трамваев, речных и морских судов и т. д.). Принцип действия основан на подаче световых сигналов. История устройства насчитывает порядка 150 лет. Первый светофор был установлен в столице Британии неподалеку от здания парламента в 1868 году. Поскольку его создатель являлся специалистом в области разработки железнодорожных семафоров, новое устройство немногим отличалось от своего прообраза. Оснащенное двумя подвижными стрелками, оно имело ручное управление.
Светофор
Сигналы, подаваемые светофором, были предназначены исключительно для транспортных средств и использовались с целью обеспечения безопасности пешеходов. Регулировка движения в темное время суток осуществлялась при помощи вращающегося газового фонаря, загоравшегося красным и зеленым цветами. В 1869 году данный элемент устройства взорвался, нанеся осколочные ранения полицейскому.
Первый светофор автоматического типа с не подсвеченными надписями «Stop» и «Proceed» был запатентован в Америке в 1910 году. Что же касается аналога современного трехцветного устройства, то он появился на улицах Нью-Йорка и Детройта спустя десять лет. В Россию данное новшество пришло лишь в 1930 году. Первый светофор был установлен в Ленинграде, второй, спустя несколько месяцев, – в Москве.
Семафор – сигнальный прибор стационарного типа, используемый на железных дорогах. Представляет собой высокую мачту с закрепленными на ней подвижными крыльями (от одного до трех), положение которых является ориентиром для машиниста. В темное время суток и при отсутствии хорошей видимости на приборе загораются сигнальные огни красного, зеленого и желтого цветов. Последний, наряду с опущенными дополнительными (вторым и третьим) крыльями семафора, свидетельствует о необходимости снижения скорости поезда.
Семафор
Горизонтальное положение верхнего указателя и запрещающий красный сигнал являются призывом к остановке транспортного средства. Тогда как расположенное под углом 135 градусов основное крыло и зеленый «маячок» говорят о том, что путь свободен. Стоит отметить, что семафоры на железной дороге были широко распространены в СССР до 1950-х годов. Во второй половине XX века им на смену пришла светофорная сигнализация. Впрочем, на некоторых участках путей по-прежнему используются устаревшие приборы.