Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
спос ответтті.doc
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
218.11 Кб
Скачать

Вопрос1

Семафор - это защищенная переменная, значение которой можно опрашивать и менять только при помощи специальных операций wait и signal и операции инициализации init. Двоичные семафоры могут принимать только значения 0 и 1. Семафоры со счетчиками могут принимать неотрицательные целые значения.

Семафоры могут использоваться для контролирования доступа к ресурсам: число в семафоре представляет собой количество процессов, которые могут получить доступ к данным. Каждый раз, когда процесс обращается к данным, значение в семафоре, должно быть уменьшено на единицу, и увеличено, когда работа с данными будет прекращена. Если ресурс эксклюзивный, то есть к данным должен иметь доступ только один процесс, то начальное значение в семафоре следует установить единицей.

Семафоры можно использовать и для других целей, например для счётчика ресурсов. В этом случае число в семафоре — количество свободных ресурсов (например количество свободных ячеек памяти).

Применение семафоров

Вот некоторые из проблем, которые могут решать семафоры.

  • запрет одновременного выполнения заданных участков кода;

  • поочерёдный доступ к критическому ресурсу (важному ресурсу, для которого невозможен одновременный доступ).

Следующий пример показывает, как наладить поочерёдный доступ к консоли.

semaphore.init(1);

Поток 1:

semaphore.enter();

cout << "Состояние массива: ";

for (int i=0; i<n; i++)

cout << a[i] << ' ';

cout << '\n';

semaphore.leave();

Поток 2:

semaphore.enter();

cout << "Нажато Esc.\n";

semaphore.leave();

Этот код поможет предотвратить появление листинга наподобие

Состояние массива: 1 2 3 Нажато Esc.

4 5 6

Семафори в мовах програмування і ОС

Семафори — високорівневий механізм взаємних виключень, який може надаватися мовою програмування або ОС. Здається першою мовою програмування, що отримала семафори, став Algol-68. Примітиви, які ми назвали wait і signal, в Algol-68 отримали імена down і up відповідно.

Інша класична мова програмування, що підтримує синхронізацію процесів за

допомогою семафорів, – Modula-2. Рекомендований автором мови Н. Віртом як стандартний модуль визначень Processes приведений в ліст. 3.7:

Лістинг 3.7.

DEFINITION MODULE Processes;

TYPE SIGNAL;

PROCEDURE StartProcess(P:PROC; n:CARDINAL); (* Почати паралельний процес, що задається програмою Р з робочою областю розміром n *)

PROCEDURE SEND(VAR s:SIGNAL); (* Відновлює один з процесів,

що чекають на s *)

PROCEDURE WAIT(VAR s:SIGNAL); (* Чекати поки не пришлють сигнал s *)

PROCEDURE Awaited(VAR s:SIGNAL): BOOLEAN; (* Якщо TRUE –

хоча б один процес чекає на s *)

PROCEDURE Init(VAR s:SIGNAL); (* Обов'язкова ініціалізація *)

END Processes.

Відзначимо наявність процедури обов'язкової ініціалізації семафора Init і неблокуючу процедуру перевірки черги процесів, що очікують на семафор Awaited.

Що стосується сучасних систем програмування на мовах C/C++, то вони, як правило, мають в своєму складі бібліотеки підтримки засобів синхронізації процесів які спираються на можливості, що надаються ОС. Так наприклад, бібліотека MFC фірми Microsoft містить класи CSemaphore і CMutex, що надають механізми семафорів і м'ютексів для багатопотокових застосувань.

Розгляд підтримки взаємних виключень засобами ОС почнемо з систем сімейства UNIX.

Системні виклики для управління потоками в UNIX-подібних ОС стандартизовані в частині стандарту POSIX (P1003.1c). Стандартом не обумовлюється спосіб реалізації викликів, так що вони можуть бути як справжніми викликами сервісів ядра системи, так і викликами бібліотечних функцій, що працюють в просторі користувача.

Деякі виклики стандарту POSIX для роботи з семафорами

Таблиця 3.2. Виклик

Опис

pthread_mutex_init

Створює новий м'ютекс

pthread_mutex_destroy

Знищує м'ютекс

pthread_mutex_lock

Захоплення м'ютекса (див. wait)

pthread_mutex_unlock

Звільнення м'ютекса (див. signal)

sem_init

Ініціалізація семафору

sem_wait

Зменшує значення лічильника (див. wait)

sem_post

Збільшує значення лічильника (див. signal)

sem_getvalue

Читає поточне значення лічильника семафору