Материал: Sb97308

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Вопросы для самопроверки

1.В чем состоит различие между понятиями «поток» и «процесс»?

2.Как передать параметры в функцию потока при создании потока?

3.Какие способы завершения потока существуют?

4.На какие характеристики потока можно влиять через атрибуты

потока?

5.В каких состояниях может находиться поток?

6.Какие способы переключения задач используются в ОС?

7.Объясните суть параметров, входящих в вызов pthread_create().

8.Объясните суть параметров, входящих в вызов pthread_join().

9.Опишите трассу выполнения программы.

6

2. СИНХРОНИЗАЦИЯ ПОТОКОВ С ПОМОЩЬЮ МЬЮТЕКСОВ И НЕИМЕНОВАННЫХ СЕМАФОРОВ

Цель работы – знакомство со средствами синхронизации потоков – мьютексами и неименованными семафорами, а также системными вызовами, обеспечивающими их создание, закрытие, захват и освобождение.

Общие сведения

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

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

Мьютекс в отличие от семафора обладает только двумя состояниями – захвачен и свободен.

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

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

Возможность присваивать семафору различные начальные значения позволяет обеспечить большее разнообразие правил нахождения потоков в критическом участке.

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

Вызов, которым создается мьютекс, выглядит следующим образом: int pthread_mutex_init(pthread_mutex_t *mutex,

const pthread_mutexattr_t *attr),

где mutex – идентификатор мьютекса; attr – указатель на структуру данных, описывающих атрибуты мьютекса.

При входе в критический участок необходимо осуществить вызов int pthread_mutex_lock(pthread_mutex_t *mutex).

7

При выходе из критического участка используется вызов int pthread_mutex_unlock(pthread_mutex_t *mutex).

Вызов, которым удаляется мьютекс, выглядит следующим образом: int pthread_mutex_destroy(pthread_mutex_t *mutex).

Создание семафора производится вызовом

int sem_init(sem_t *sem, int shared, unsigned int value),

где sem – идентификатор семафора; shared – индикатор использования семафора потоками или процессами; value – начальное значение счетчика семафора.

При входе в критический участок необходимо использовать вызов int sem_wait(sem_t *sem).

При выходе из критического участка используется вызов int sem_post(sem_t *sem).

Удаление семафора производится вызовом

int sem_destroy(sem_t *sem).

Указания к выполнению работы

Написать программу, содержащую 2 потока, осуществляющих координированный доступ к разделяемому ресурсу (ресурс выбрать самостоятельно, например экран или файл).

Необходимо убедиться, что при отсутствии мьютекса (семафора) потоки выводят символы на экран в произвольном порядке, например:

121212121212121212121212121212121212121212121212121212121212121.

При использовании мьютекса (семафора) потоки выводят символы на экран в определенном порядке, например:

111111111122222222221111111111222222222211111111112222222222.

По согласованию с преподавателем выбрать средство координации – мьютексы или неименованные семафоры.

Шаблон программы:

объявить флаг завершения потока 1; объявить флаг завершения потока 2;

объявить идентификатор мьютекса /*неименованного семафора*/; функция потока 1()

{

8

пока (флаг завершения потока 1 не установлен)

{

захватить мьютекс /*неименованный семафор*/; в цикле несколько раз выполнять

{

выводить символ ‘1’ на экран; задержать на время;

}

освободить мьютекс /*неименованный семафор*/; задержать на время;

}

}

функция потока 2()

{

пока (флаг завершения потока 2 не установлен)

{

захватить мьютекс /*неименованный семафор*/; в цикле несколько раз выполнять

{

выводить символ ‘2’ на экран; задержать на время;

}

освободить мьютекс /*неименованный семафор*/; задержать на время;

}

}

основная программа()

{

объявить идентификатор потока 1; объявить идентификатор потока 2;

инициализировать мьютекс /*неименованный семафор*/; создать поток из функции потока 1; создать поток из функции потока 2; ждать нажатия клавиши; установить флаг завершения потока 1;

установить флаг завершения потока 2;

9

ждать завершения потока 1; ждать завершения потока 2;

удалить мьютекс /*неименованный семафор*/;

}

Вопросы для самопроверки

1.Какой ресурс называется критическим ресурсом?

2.Какой участок программы называется критическим участком?

3.Какой режим выполнения программ называется режимом взаимного исключения?

4.Перечислите способы организации режима взаимного исключения.

5.Опишите алгоритмы операций захвата и освобождения мьютекса.

6.Опишите алгоритмы операций захвата и освобождения семафора.

7.Какими операциями с мьютексом и с неименованным семафором можно проверить занятость ресурса без блокирования потока?

10