Литературное чтение
<<  Для чтения взрослыми детям Аналитическое чтение поэмы  >>
Блокировки чтения-записи
Блокировки чтения-записи
Введение
Введение
Введение
Введение
Введение
Введение
Введение
Введение
Получение и сброс блокировки чтения-записи
Получение и сброс блокировки чтения-записи
Получение и сброс блокировки чтения-записи
Получение и сброс блокировки чтения-записи
Получение и сброс блокировки чтения-записи
Получение и сброс блокировки чтения-записи
Получение и сброс блокировки чтения-записи
Получение и сброс блокировки чтения-записи
Атрибуты блокировки чтения-записи
Атрибуты блокировки чтения-записи
Атрибуты блокировки чтения-записи
Атрибуты блокировки чтения-записи
Атрибуты блокировки чтения-записи
Атрибуты блокировки чтения-записи
Атрибуты блокировки чтения-записи
Атрибуты блокировки чтения-записи
Атрибуты блокировки чтения-записи
Атрибуты блокировки чтения-записи
Реализация
Реализация
Реализация
Реализация
Реализация
Реализация
Реализация
Реализация
Реализация
Реализация
Реализация
Реализация
Реализация
Реализация
Реализация
Реализация
Реализация
Реализация
Реализация
Реализация
Реализация
Реализация
Реализация
Реализация
Отмена выполнения потоков
Отмена выполнения потоков
Отмена выполнения потоков
Отмена выполнения потоков
Отмена выполнения потоков
Отмена выполнения потоков
Пример
Пример
Пример
Пример
Пример
Пример
Пример
Пример
Пример
Пример

Презентация: «Блокировки чтения-записи». Автор: Гунько Андрей Васильевич. Файл: «Блокировки чтения-записи.pps». Размер zip-архива: 75 КБ.

Блокировки чтения-записи

содержание презентации «Блокировки чтения-записи.pps»
СлайдТекст
1 Блокировки чтения-записи

Блокировки чтения-записи

Введение Получение и сброс блокировки чтения-записи Атрибуты блокировки чтения-записи Реализация Отмена выполнения потоков Пример

2 Введение

Введение

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

3 Введение

Введение

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

4 Введение

Введение

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

5 Введение

Введение

Такой вид совместного доступа к ресурсу также носит название совместно-исключающей блокировки (shared-exclusive), поскольку тип используемой блокировки на чтение называется совместной блокировкой (shared lock), а тип используемой блокировки на запись называется исключающей блокировкой (exclusive lock).

6 Получение и сброс блокировки чтения-записи

Получение и сброс блокировки чтения-записи

Блокировка чтения-записи имеет тип pthread_rwlock_t. Если переменная этого типа является статической, она может быть проинициализирована присваиванием значения константы PTHREAD_RWLOCK_INITIALIZER. Функция pthread_rwlock_rdlock позволяет заблокировать ресурс для чтения, причем вызвавший процесс будет заблокирован, если блокировка чтения-записи уже установлена записывающим процессом.

7 Получение и сброс блокировки чтения-записи

Получение и сброс блокировки чтения-записи

Функция pthread_rwlock_wrlock позволяет заблокировать ресурс для записи, причем вызвавший процесс будет заблокирован, если блокировка чтения-записи уже установлена каким-либо другим процессом (считывающим или записывающим). Функция pthread_rwlock_unlock снимает блокировку любого типа (чтения или записи). Все функции возвращают 0 в случае успешного завершения, положительное значение Еххх - в случае ошибки.

8 Получение и сброс блокировки чтения-записи

Получение и сброс блокировки чтения-записи

#include <pthread.h> int pthread_rwlock_rdlock (pthread_rwlock_t *rwptr); int pthread_rwlock_wrlock (pthread_t rwlock_t *rwptr); int pthread_rwlock_unlock ( pthread_rwlock_t *rwptr);

9 Получение и сброс блокировки чтения-записи

Получение и сброс блокировки чтения-записи

Следующие две функции производят попытку заблокировать ресурс для чтения или записи, но если это невозможно, возвращают ошибку с кодом EBUSY, вместо того чтобы приостановить выполнение вызвавшего процесса: #include <pthread.h> int pthread_rwlock_tryrdlock (pthread_rwlock_t *rwptr); int pthread_rwlock_trywrlock (pthread_rwlock_t *rwptr);

10 Атрибуты блокировки чтения-записи

Атрибуты блокировки чтения-записи

Статическая блокировка может быть проинициализирована присваиванием ей значения PTHREAD_RWLOCK_INITIALIZER. Эти переменные могут быть проинициализированы и динамически путем вызова функции pthread_rwlock_init. Когда поток перестает нуждаться в блокировке, он может вызвать pthread_rwlock_destroy:

11 Атрибуты блокировки чтения-записи

Атрибуты блокировки чтения-записи

#include <pthread.h> int pthread_rwlock_init (pthread_rwlock_t *rwptr, const pthread_rw1ockattr_t *attr); int pthread_rwlock_destroy (pthread_rwlock_t *rwptr); Обе функции возвращают 0 в случае успешного завершения положительное значение Еххх - в случае ошибки.

12 Атрибуты блокировки чтения-записи

Атрибуты блокировки чтения-записи

Если при инициализации блокировки чтения-записи attr представляет собой нулевой указатель, атрибутам присваиваются значения по умолчанию. Для присваивания атрибутам других значений следует воспользоваться двумя функциями: #include <pthread.h> int pthread_rwlockattr_init (pthread_rwlockattr_t *attr); int pthread_rwlockattr_destroy (pthread_rw1ockattr_t *attr);

13 Атрибуты блокировки чтения-записи

Атрибуты блокировки чтения-записи

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

14 Атрибуты блокировки чтения-записи

Атрибуты блокировки чтения-записи

#include <pthread.h> int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *attr, int *valptr); int pthread_rwlockattr_setpshared (pthread_rwlockattr_t *attr, int value); Первая функция возвращает текущее значение в целом, на которое указывает аргумент valptr. Вторая функция устанавливает значение этого атрибута равным value, которое может быть либо PTHREAD_PROCESS_PRIVATE, либо PTHREAD_PROCESS_SHARED.

15 Реализация

Реализация

В листинге 1 приведен текст заголовочного файла pthread_rwlock.h, в котором определен основной тип pthread_rwlock_t и прототипы функций, работающих с блокировками чтения и записи Обычно все это находится в заголовочном файле <pthread.h>

16 Реализация

Реализация

3-13 Наш тип pthread_rwlock_t содержит одно взаимное исключение, две условные переменные, один флаг и три счетчика. При просмотре или изменении содержимого этой структуры мы должны устанавливать блокировку rw_mutex. После успешной инициализации структуры полю rw_magic присваивается значение RW_MAGIC. Значение этого поля проверяется всеми функциями — таким образом гарантируется, что вызвавший поток передал указатель на проинициализированную блокировку. Оно устанавливается в 0 после уничтожения блокировки.

17 Реализация

Реализация

Обратите внимание, что в счетчике rw_refcount всегда хранится текущий статус блокировки чтения-записи: -1 обозначает блокировку записи (и только одна такая блокировка может существовать в любой момент времени), 0 обозначает, что блокировка доступна и может быть установлена, а любое положительное значение соответствует количеству установленных блокировок на чтение. 14-17 Мы также определяем константу для статической инициализации нашей структуры.

18 Реализация

Реализация

Первая функция, pthread_rwlock_init, динамически инициализирует блокировку чтения-записи. Ее текст приведен в листинге 2. 7-8 Присваивание атрибутов с помощью этой функции не поддерживается, поэтому мы проверяем, чтобы указатель attr был нулевым. 9-19 Мы инициализируем взаимное исключение и две условные переменные, которые содержатся в нашей структуре. Все три счетчика устанавливаются в 0, а полю rw_magiс присваивается значение, указывающее на то, что структура была проинициализирована.

19 Реализация

Реализация

20-25 Если при инициализации взаимного исключения или условной переменной возникает ошибка, мы уничтожаем проинициализированные объекты и возвращаем код ошибки. В листинге 3 приведена функция pthread_rwlock_destroy, уничтожающая блокировку чтения-записи после окончания работы с ней. 8-13 Прежде всего проверяется, не используется ли блокировка в данный момент, а затем вызываются соответствующие функции для уничтожения взаимного исключения и двух условных переменных.

20 Реализация

Реализация

Функция pthread_rwlock_rdlock выполняет получение блокировки на чтение. 9-10 При работе со структурой pthread_rwlock_t всегда устанавливается блокировка на rw_mutex, являющееся ее полем. 11-18 Нельзя получить блокировку на чтение, если rw_refcount имеет отрицательное значение (блокировка установлена на запись) или имеются потоки, ожидающие получения блокировки на запись (rw_nwaitwriters больше 0).

21 Реализация

Реализация

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

22 Реализация

Реализация

В листинге 5 показана функция pthread_rwlock_tryrdlock, которая не вызывает приостановления вызвавшего ее потока. 11-14 Если блокировка в данный момент установлена на запись или есть процессы, ожидающие возможности установить ее на запись, возвращается ошибка с кодом EBUSY. В противном случае мы устанавливаем блокировку, увеличивая значение счетчика rw_refcount.

23 Реализация

Реализация

Текст функции pthread_rwlock_wrlock приведен в листинге 6. 11-17 Если ресурс заблокирован на считывание или запись (значение rw_refcount отлично от 0), мы приостанавливаем выполнение потока. Для этого мы увеличиваем rw_nwaitwriters и вызываем pthread_cond_wait с условной переменной rw_condwriters. Для этой переменной посылается сигнал при снятии блокировки чтения-записи, если имеются ожидающие разрешения на запись процессы. 18-19 После получения блокировки на запись устанавливаем значение rw_refcount в -1.

24 Реализация

Реализация

Неблокирующая функция pthread_rwlock_trywrlock показана в листинге 7. 11-14 Если значение счетчика rw_refcount отлично от нуля, блокировка в данный момент уже установлена считывающим или записывающим процессом (это безразлично) и мы возвращаем ошибку с кодом EBUSY. В противном случае мы устанавливаем блокировку на запись, присвоив переменной rw_refcount значение -1.

25 Реализация

Реализация

Последняя функция, pthread_rwlock_unlock, приведена в листинге 8. 16 Если rw_refcount больше 0, считывающий поток снимает блокировку на чтение. Если rw_refcount равно -1, записывающий поток снимает блокировку на запись. 22 Если имеются ожидающие разрешения на запись потоки, по условной переменной rw_condwnters передается сигнал (если блокировка свободна, то есть значение счетчика rw_refcount равно 0).

26 Реализация

Реализация

Мы знаем, что только один поток может осуществлять запись, поэтому используем функцию pthread_cond_signal. Если нет потоков, ожидающих возможности записи, но есть потоки, ожидающие возможности чтения, мы вызываем pthread_cond_broadcast для переменной rw_condreaders, поскольку возможно одновременное считывание несколькими потоками.

27 Отмена выполнения потоков

Отмена выполнения потоков

Отмена выполнения может быть использована в том случае, если несколько потоков начинают работу над какой-то задачей (например, поиск записи в базе данных) и один из них завершает работу раньше всех остальных. Тогда он может отменить их выполнение. Другим примером является обнаружение ошибки одним из одновременно выполняющих задачу потоков, который затем может отменить выполнение и всех остальных. Для обработки отмены выполнения поток может установить (push) или снять (pop) обработчик-очиститель (cleanup handler):

28 Отмена выполнения потоков

Отмена выполнения потоков

#include <pthread.h> void pthread_cleanup_push(void (*function)(void *), void *arg); void pthread_cleanup_pop(int execute); Эти обработчики вызываются: в случае отмены выполнения потока (другим потоком, вызвавшим pthread_cancel); в случае добровольного завершения работы (вызовом pthread_exit или выходом из начальной функции потока).

29 Отмена выполнения потоков

Отмена выполнения потоков

Обработчики-очистители выполняют всю необходимую работу по восстановлению значений переменных, такую как разблокирование взаимных исключений и семафоров, которые могли быть заблокированы данным потоком. Аргумент function представляет собой адрес вызываемой функции, a arg — ее единственный аргумент. Функция pthread_cleanup_pop всегда удаляет обработчик из верхушки стека и вызывает эту функцию, если значение execute отлично от 0.

30 Пример

Пример

31 Пример

Пример

На рисунке изображена временная диаграмма выполнения нашей программы, а текст самой программы приведен в листинге 9. 3 Создаются два потока, первый из которых выполняет функцию threadl, а второй — thread2. После создания первого делается пауза длительностью в одну секунду, чтобы он успел заблокировать ресурс на чтение. 14-23 Мы ожидаем завершения работы второго потока и проверяем, что его статус. Затем мы ждем завершения работы первого потока и проверяем его статус. Затем мы уничтожаем блокировку.

32 Пример

Пример

Поток 1 получает блокировку на чтение и ждет 3 секунды. Эта пауза дает возможность другому потоку вызвать pthread_rwlock_wrlock и заблокироваться при вызове pthread_cond_wait, поскольку блокировка на запись не может быть установлена из-за наличия блокировки на чтение. Затем первый поток вызывает pthread_cancel для отмены выполнения второго потока, ждет 3 секунды, освобождает блокировку на чтение и завершает работу.

33 Пример

Пример

Второй поток делает попытку получить блокировку на запись (которую он может получить, когда первый поток снимет блокировку на чтение). Однако первый поток послал сигнал на отмену второго, что и произойдет после его разблокирования. Если первый поток не снимет блокировку (test 1), то второй не будет завершен и программа зависнет.

34 Пример

Пример

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

«Блокировки чтения-записи»
http://900igr.net/prezentacija/literatura/blokirovki-chtenija-zapisi-215965.html
cсылка на страницу
Урок

Литература

183 темы
Слайды