Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект лекций СПО 31-8-13.doc
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
970 Кб
Скачать
☆

Interlocked – функции.

Для увеличения или уменьшения на единицу глобальных переменных типа long:

InterlockedIncrement(I);

InterlockedDecrement(I);

Возвращают: 0 – при переходе через 1; положительное число, если результат больше 0; отрицательное число, если результат меньше 0.

Обмен переменными:

InterlockedExchange (LTarget, LValue);

Обеспечивает правильное увеличение (уменьшение) глобальной переменной типа longint без использования критических секций или мьютексов.

Общее решение: использование средств синхронизации операционной системы:

- критических секций;

- мьютексов (Mutex – mutually exclusive – взаимоисключающие);

- семафоров.

Требования к средствам доступа к критическим участкам:

1. В любой момент времени только один поток может находиться в критическом участке;

2. Ни один поток не должен находиться в критическом участке бесконечно долго;

3. Ни один поток не должен ждать бесконечно долго входа в критический участок;

4. Поток завершившийся (аварийно) в критическом участке, не должен блокировать вход в критический участок для других потоков.

Пример 2: Сотрудничающие потоки – задача «поставщик-потребитель».

Поток - поставщик создает порции данных для передачи (через линии связи), а поток - потребитель передает их. Для хранения сообщений используется совокупность (пул) буферов на одно сообщение.

Рисунок 1 – 8 - Взаимодействие поставщика и потребителя

Поставщик и потребитель должны синхронизировать свои действия – поставщик может передавать сообщения, когда есть свободное буферы в очереди, потребитель – может получать сообщения, если очередь не пуста.

Средства синхронизации параллельных потоков без поддержки ОС

Чисто программное решение без поддержки ОС. Достоинства, недостатки

Чисто программное решение использует цикл активного ожидания –

While < условие > do;

Два варианта – использование признака «критический участок занят»

и поочередный вход в критический участок

Первый вариант некорректен, второй требует примерно одинаковой скорости выполнения потоков.

Достоинства – простота, независимость от операционной системы.

Недостатки – потеря времени в цикле активного ожидания, инверсия приоритетов

Семафорные примитивы Дейкстры

Семафор – переменная специального, типа доступная для выполнения операций

  1. P(S) - открыть

  2. V(S) - закрыть

Смысл операции P(S) состоит

P(S) – S>0 => S:=S-1 и поток имеет возможность продолжится

Иначе – (S0) - остановить поток (поставить в очередь)

V(S) –если S0 – поместить один ожидающих потоков в очередь готовности.

S:=S-1

InitSem (S, нач. знач.) – S:= нач значение

Решение проблемы критических участков с помощью семафорных примитивов Дейкстры

InitSem (S,1)

Поток1

WhileTrue do

Begin

P(S); S=0

Критический участок

V(S); S=1

End;

Поток2

WhileTrue do

Begin

P(S)

Критический участок

V(S)

End;

1.3.4 Синхронизации потоков средствами операционной системы

Средства синхронизации потоков.

Это средства ОС Windows, которые являются общими для всех потоков в системе и используются для координирования доступа к ресурсам. Их можно разделить на средства синхронизации пользовательского режима и средства синхронизации режима ядра.

Средство синхронизации пользовательского режима – критические секции.

Средства синхронизации рассмотренной ранее критической секции и Interlocted – функции – работают весьма быстро, поскольку процессор при их использовании переводится в режим ядра на непродолжительное время, однако их возможности ограничены. Другие средства синхронизации используют режим ядра (каждый переход в режим ядра занимает около1000 тактов ЦП) и поэтому работают медленнее, чем средства синхронизации последовательного режима.

Критическая секция должна быть описана и инициализирована вызовом функции InitializeCriticalSection (Sect1).

Перед операциями с общими переменными в искомом потоке помещается вызов функции: EnterCriticalSection (Sect1);

//операции с общими переменными

LeaveCriticalSection (Sect1);

Если поток 1 пытается войти в критическую секцию и она не занята, то ему это позволяется функцией EnterCriticalSection (Sect1), ставится флаг занятости, тогда поток 2 при попытке сделать то же самое переводится в состояние ожидания (Sleep) до тех пор, пока поток 1 не выполнит LeaveCriticalSection (Sect1).

После завершения работы с критической секцией ее необходимо удалить с помощью вызова функции DeleteCriticalSection (Sect1).

Функция TryEnterCriticalSection(Sect1) –проверяет, занята ли критическая секция в данный момент, поток может заняться чем-либо другим, ожидая доступ к критическому участку.

Объекты ядра, использующиеся для синхронизации потоков.

  1. Mutex (Mutualli Exclusive – взаимное исключение)

  2. Semaphore - семафор.

  3. Events – событие

  4. Process – процесс

  5. Thread – поток

  6. JOB – задания

  7. File – файл

  8. Консольный ввод/вывод

  9. Notification –уведомление

Создание объекта ядра **** выполняется с помощью функций вида

Create **** (атрибут безопасности, …)

Мьютексы

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

Создание мьютекса

CreateMutex (nil, initOwnes - начальный владелец, boolean true: владелец-поток который создал его, False: владелец 1-й обратившийся поток, имя) : Thandle

Используется для синхронизации потоков, принадлежащих разным процессам.

Если 2-й параметр true, то данный поток становится владельцем мьютекса, объект mutex будет занят. Любой другой поток будет приостановлен, пока первый поток не освободит его.

Передача false показывает что mutex не принадлежит ни одному потоку, и поэтому «рождается свободным». Любой поток может захватить его и продолжить его выполнение. Мьютексы способны синхронизировать потоки, выполняемые в разных процессах.

Функции ожидания одного или нескольких событий

Функции - WaitForSingleObject() и WaitForMultipleObjects () - назначение и аргументы

Вызов функции WaitForSingleObject () оказывает влияние на некоторые объекта ядра.

Пример 1

Поток_1

WaitForSingleObject(Handle Process, ………) либо Handle Thread, …….)

Если в момент выполнения потоком_1 процесс Handle Process (или поток Handle Thread) выполняются, поток_1 будет ждать, пока процесс или поток Thread завершится. Как только это произойдет, объект Handle Process, Handle Thread получит статус свободного и поток_1 продолжит работу.