К Т П           План занятия                                                              1                                           Страницы  | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 8 | | 9 |

8. Примитив синхронизации semaphore (семафор)

Ниже приведен класс Semaphore, определяющий одноименный примитив.


class Semaphore
{
unsigned counter; // счетчик
ThreadQueue tq;
public: // очередь потоков
Semaphore(unsigned n): counter(n) {} // конструктор
~Semaphore() {}                      // деструктор
void Signal() // сигнализировать о том, что условие выполнено
{
disable interrupt(); // запрещаем прерывания
if(!tq.DequeueThread())
++counter;
enable interrupt(); } // разрешаем прерывания
}
void Wait(Thread t) // ждать выполнения условия
{
disable interrupt();// запрещаем прерывания
if(counter > 0)
--counter;
// сбрасываем условие
else
tq.EnqueueThread(t); // ставим поток в очередь ожидания
enable_interrupt(); // разрешаем прерывания

}
};

При помощи примитива semaphore (семафор) также могут быть решены задачи условной синхронизации и взаимного исключения. Эти решения полностью совпадают с решениями, использующими примитив condition (условие) за исключением того, что семафор должен принимать значения 0 и 1 вместо true и false соответственно.

Семафор, который может принимать только значения 0 или 1 называется бинарным. Такой семафор собственно ничем не отличается от примитива синхронизации condition (условие). Если же семафор может принимать любые положительные целочисленные значения, то такой семафор называется считающим. Считающие семафоры используются для подсчета количества ресурсов, производимых параллельными потоками. Такие потоки обычно называются производителями. Уменьшают значение считающего семафора потоки, которые потребляют эти ресурсы, такие потоки называются потребителями.

Сделаем еще одно замечание относительно семафоров, которое, впрочем, касается и примитива синхронизации condition (условие). Если очередь семафора обслуживается по алгоритму FIFO, то семафор называется сильным, а в противном случае слабым. На этот момент следует обратить внимание при разработке приложений. Если в спецификациях операционной системы ничего не сказано о порядке обслуживания очереди потоков, ждущих некоторого события или положительного значения семафора, то не нужно делать на этот счет никаких предположений. Так как потоки, стоящие в очереди к примитиву синхронизации, могут обслуживаться как по алгоритму FIFO, так и учитывая их приоритеты.

 


Предыдущая        В начало страницы       Следующая
8