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

Устранение блокировок

Если поток, захвативший ресурс, завершится, не освободив его, например, аварийно, то потоки, ожидающие ресурс, т.е. вызвавшие операции pthread_mutex_lock() или sem_wait(), так и останутся в заблокированном состоянии.

Устранить проблему позволяют неблокирующие операции проверки занятости ресурсов.

Для мьютексов это следующие операции:

  1. int pthread_mutex_trylock(pthread_mutex_t *mutex);

Если ресурс свободен, то функция работает также как и функция pthread_mutex_lock(). Если ресурс занят, то функция не блокируется в ожидании освобождения ресурса, а сразу же возвращает управление с кодом ошибки EBUSY.

  1. int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abs_timeout);

Если ресурс свободен, то функция работает также как и функция pthread_mutex_lock(). Если ресурс занят, то функция блокируется в ожидании освобождения ресурса до времени abs_timeout. Если в течение времени ожидания ресурс не освободится, функция завершается с кодом ошибки ETIMEDOUT.

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

Для получения текущего времени можно использовать функцию:

int clock_gettime(clockid_t clk_id, struct timespec *tp);

где:

clockid_t clk_id тип часов, например, CLOCK_REALTIME,

время задается в виде структуры:

struct timespec {

time_t tv_sec; /* секунды */

long tv_nsec; /* наносекунды */

};

Например, чтобы получить время ожидания 1 сек, надо выполнить следующие действия:

  1. вызовом clock_gettime получить время в структуру tp,

  2. выполнить операцию tp.tv_sec += 1,

  3. передать модифицированное значение tp в функцию pthread_mutex_timedlock.

Для семафоров неблокирующими являются следующие функции:

int sem_trywait(sem_t *sem);

Если ресурс свободен, то функция работает также как и функция sem_wait(). Если ресурс занят, то функция не блокируется в ожидании освобождения ресурса, а сразу же возвращает управление с кодом ошибки EAGAIN.

И функция:

int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);

Время ожидания устанавливается аналогично предыдущему варианту.

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

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

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

121212121212121212121212121212121212121212121212121212121212121.

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

111111111122222222221111111111222222222211111111112222222222.

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

В обоих случаях студент реализует три варианта программы:

  1. С блокирующей операцией захвата мьютекса (семафора) pthread_mutex_lock() (sem_wait());

  2. С операцией проверки захвата мьютекса (семафора) без блокировки pthread_mutex_trylock() (sem_trywait());

  3. С блокировкой на время операции захвата мьютекса (семафора) pthread_mutex_timedlock() (sem_timedwait()).

Шаблон программы представлен ниже:

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

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

объявить идентификатор мьютекса /*неименованного семафора*/;

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

{

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

{

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

в цикле несколько раз выполнять

{

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

задержать на время;

}

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

задержать на время;

}

}

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

{

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

{

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

в цикле несколько раз выполнять

{

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

задержать на время;

}

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

задержать на время;

}

}

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

{

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

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

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

создать поток из функции потока 1;

создать поток из функции потока 2;

ждать нажатия клавиши;

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

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

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

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

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

}

Соседние файлы в предмете Операционные системы