Добавил:
Developer Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторные методички по Си / СОС Лабораторная работа №4 Си.docx
Скачиваний:
6
Добавлен:
25.03.2023
Размер:
47.46 Кб
Скачать

3.5. Синхронизация потоков

При выполнении нескольких потоков во многих случаях необходимо синхронизировать их взаимодействие. Существует несколько способов синхронизации потоков:

  взаимные исключения – мьютексы (Mutex – MUTial EXclusion);

  переменные состояния;

 семафоры.

Механизм использования переменных состояния и семафоров в многопоточных приложениях аналогичен механизму использования этих методов синхронизации в многопроцессных приложениях.

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

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

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

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

Объекты синхронизации можно также разместить в файлах, где они будут существовать независимо от создавшего их процесса.

Необходимость в синхронизации потоков возникает в следующих случаях:

Если синхронизация – это единственный способ гарантировать последовательность разделяемых (общих) данных.

Если потоки в двух или более процессах могут использовать един- ственный объект синхронизации совместно. При этом объект синхронизации должен инициализироваться только одним из взаимодействующих процессов, потому что повторная инициализация объекта синхронизации устанавливает его в открытое состояние.

Если синхронизация может гарантировать достоверность изменяющихся данных.

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

4. Мьютексы

4.1. Функции синхронизации потоков с использованием мьютексов

Для синхронизации потоков с использованием мьютексов используются следующие основные функции:

pthread_mutex_init – инициализирует взаимоисключающую блоки- ровку;

pthread_mutex_destroy – удаляет взаимоисключающую блокировку;

pthread_mutex_lock – устанавливает блокировку; в случае, если блокировка была установлена другим потоком, текущий поток останавливается до снятия блокировки другим процессом;

pthread_mutex_unlock – снимает блокировку.

4.2. Инициализация и удаление объекта атрибутов мьютекса

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

Функция

int pthread_mutexattr_init (pthread_mutexattr_t* mattr)

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

Пример вызова функции pthread_mutexattr_init:

#include <pthread.h> pthread_mutexattr_t mattr; int ret;

/* инициализация атрибутов значениями по умолчанию */ ret = pthread_mutexattr_init(&mattr);

Для корректного удаления объекта атрибутов, созданного с помощью функции pthread_mutexattr_init, необходимо вызвать функцию pthread_mutexattr_destroy. В противном случае возможна утечка памяти, так как тип pthread_mutexattr_t является закрытым. Она возвращает 0 после успешного завершения или другое значение, если произошла ошибка. Пример вызова функции pthread_mutexattr_destroy:

#include <pthread.h> pthread_mutexattr_t mattr; int ret; /* удаление атрибутов */ ret = pthread_mutexattr_destroy(&mattr);