Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
26
Добавлен:
17.04.2013
Размер:
65.54 Кб
Скачать

Сравнение семафоров и мониторов

Попробуем создать на основе семафоров все необходимые для мониторов конструкции.

Во-первых с помощью семафора легко создается lock.

Как насчет такого?

Wait() { semaphore->P(); }

Signal() { semaphore->V(); }

Так грубо нельзя моделировать переменные условия, вспомним, что wait иsignal вызываются из критической секции и такое решение может привести к блокировке.

Уточним.

Wait(Lock *lock) {

lock->Release();

semaphore->P();

lock->Acquire();

}

Signal() { semaphore->V(); }

Переменные условий не имеют памяти, поэтому signal, когда никто не ждет эквивалентен пустому оператору. Последующийwait приведет к ожиданию. С семафорами это не так.

Можно ли решить проблему таким образом?

Signal() {

if(очередь семафора не пуста)

semaphore->V();

}

Нет. Во-первых не корректно смотреть на очередь семафора. Во-вторых, если остановиться в waitпосле освобожденияlock , но доP операции, то сигнал не сработает.

В принципе проблема решается. Это для самостоятельного решения.

Поддержка синхронизации в языках программирования

Проблема в том, что программист должен расставить lock в начале функции монитора иrelease в каждой точке выхода.

C

Поддержки нет необходимо отследить все выходы из функций монитора.

C++

Более проблематично, так как язык поддерживает обработку исключительных ситуаций.

Java

Имеет явную поддержку для нитей и синхронизации.

class Shared {

private int value;

public Shared(int initial){ value = initial;}

public synchronized int get() { return value; }

public synchronized void add(int incr) { value += incr; }

}

С объектом Shared связан lock, который захватывается и освобождается автоматически при входе и выходе изsynchronized методов.

Кроме того, в Java имеется операторsynchronized с помощью которого можно защищать любой участок кода. Важно, чтоlock будет освобожден, даже если выход из этого участка кода происходит в результатеexception.

synchronized (object) {

...

some_function();

...

}

Как организуется ожидание в синхронизированных методах?

void wait(long timeout);

void wait();

Как сигнализировать о наступлении события в синхронизированных методах?

void notify();

void notifyAll();

Заметим, что фактически, имеется одна условная переменная (неявная).

Разные Java машины могут вести себя по разному. Это обусловлено тем, что в языке не специфицирован механизм планирования и он может быть разным.

Передача сообщений

Семафоры и мониторы используются для синхронизации доступа к разделяемым переменным, но не имеют средств для передачи данных от одного к другому.

Механизм передачи сообщений позволяет организовать синхронизацию и взаимодействие процессов с разделенными адресными пространствами, как на одной так и на нескольких машинах.

  • Сообщения– передаются в виде пакетов фиксированной длины адресату

Sender: Receiver:

SendMessage(msg, msgsize, dest); ReceiveMessage(&msg) или

SendMessage(msg, msgsize, mailbox); ReceiveMessage(&buf, mailbox)

  • Потоки– неструктурированный поток байтов от отправителя к адресату

Sender: Receiver:

Handle = OpenConnection(destAddr); Handle = WaitForConnection();

Handle.write(buf, nBytes); While( !handle.eof() ) {

. . . Handle.read(buf, nBytes);

Handle.write(buf, nBytes); // Обработка

Handle.Close(); }

Множество разновидностей: однонаправленные и двунаправленные, с ожиданием и без ожидания, …

Адресация:

  • Прямая (threadID)

  • Косвенная через «почтовый ящик». Допускает присвоение прав на чтение-запись в почтовый ящик

  • Косвенная по имени сервиса. Принимающий процесс регистрирует себя в общедоступном списке сервисов. Передающий шлет сообщения в адрес сервиса.

Соседние файлы в папке вар1