Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Архитектура компьютеров / 10_Большие системы.doc
Скачиваний:
57
Добавлен:
20.03.2015
Размер:
389.63 Кб
Скачать

10.6.1. Доступ к общим переменным

Предположим, что мы определили две задачи, которые могут параллельно вы­полняться мультипроцессорной системой. Эти задачи почти полностью незави­симы, но время от времени они считывают и модифицируют некоторую общую переменную, хранящуюся в глобальной памяти. Пусть, например, общая пере­менная SUM представляет баланс некоторого счета. Этот счет должен обновлять­ся несколькими задачами, выполняющимися разными процессорами. Каждая за­дача производит с переменной SUM следующие действия: считывает ее текущее значение, выполняет некоторую операцию с его использованием, а результат со­храняет в переменной SUM. Нетрудно представить себе, какие ошибки могут воз­никнуть, если такие операции с переменой SUM будут осуществляться задачами Т1 и Т2, выполняющимися в параллельном режиме процессорами Р1 и Р2. Пред­положим, что обе задачи, Т1 и Т2, считывают текущее значение переменной SUM, скажем 17, и каждая по отдельности его модифицирует. Задача Т1 прибавляет к не­му 5, получая 22, а задача Т2 вычитает из него 7, результатом чего является число 10. Затем каждая из задач заносит в переменную SUM свой результат — сначала это действие выполняет задача Т2, затем задача Т1. Теперь в переменной SUM хранится число 22, что является ошибкой, так как на самом деле в этой перемен­ной должно находиться значение l5 (17 +5-7), которое получится при строго последовательном проведении изменений.

Для того чтобы обеспечить правильную работу с переменной SUM, каждая задача должна получать к ней монопольный доступ на все время выполнения последовательности операций чтения, модификации и записи. С этой целью мо­жет быть задействована глобальная переменная блокировки LOCK и машинная команда Test and Set. Переменная LOCK может принимать значение 0 или 1. Мы используем ее для того, чтобы гарантировать, что никакие две задачи не смогут одновременно получить доступ к переменной SUM. Последовательность команд, для выполнения которой требуется монопольный доступ к некоторой перемен­ной, называется критической секцией программы. Переменная LOCK использует­ся следующим образом. Если ни одна из задач не находится в состоянии выпол­нения критической секции, оперирующей переменной SUM, переменная LOCK равна 0. Когда какая-либо из задач собирается модифицировать переменную SUM, она сначала проверяет значение переменной LOCK, а затем устанавливает таковое в 1 независимо от ее исходного значения переменной. Если исходным значением является 0, задача приступает к работе с переменной SUM, поскольку это означает, что никакая другая задача с этой переменной в данный момент не работает. Если же исходное значение переменной LOCK равняется 1, значит, с переменной SUM работает другая задача. В таком случае первая задача должна находиться в состоянии ожидания до тех пор, пока вторая не установит значение переменной LOCK в 0, и лишь затем она может приступать к собственной опера­ции с этой переменной. Все перечисленные операции с переменной LOCK выпол­няются командой Test and Set. Эта команда в соответствии со своим названием не­заметно для программы выполняет проверку и установку переменной LOCK. В процессе ее работы соответствующий модуль памяти не должен отвечать на за­просы доступа от других процессоров.

TaskTl

……

LOCK1 TAS.B LOCKBYTE

BMI LOCK1

«Модификация SUM» Критическая секция

CRL.B LOCKBYTE

…..

TaskT2

…..

LOCK2 TAS.B LOCKBYTE

BMI LOCK2

«Модификация SUM» Критическая секция

CRL.B LOCKBYTE

…..

Рис. 10.14. Совместный доступ к критической секции программы

Рассмотрим конкретный пример — действие команды Test and Set (или TAS) микропроцессора 68000 компании Motorola. Один из операндов этой команды имеет размер 1 байт. Предположим, что данный операнд хранится в памяти по ад­ресу LOCKBYTE. Бит b7 старший бит этого операнда — выполняет роль опи­санной выше переменной LOCK. При осуществлении командой TAS операций проверки и установки бита b7 прерываний не происходит. Флагу кода условия N (отрицательное значение) присваивается исходное значение бита Бит b7. Если флаг N равен 0, по завершении выполнения команды TAS программа может войти в кри­тическую секцию, а если он равен 1, программа должна подождать, пока он не примет значение 0. На рис. 10.14 показано, как две задачи, Т1 и Т2, манипулиру­ют переменной LOCKBYTE для входа в критическую секцию кода, где они об­новляют общую переменную SUM. За командой TAS следует команда условно­го перехода. При N=1 опять производится переход к команде TAS, в результате чего получается цикл ожидания, в котором эта команда выполняется над операн­дом по адресу LOCKBYTE до тех пор, пока бит b7 не примет значение 0. Если бит b7 = 0, переход к команде TAS не осуществляется и программа входит в критическую секцию. По завершении выполнения критической секции переменная LOCK­BYTE очищается. В результате бит b7 устанавливается в 0 и ожидающая этого программа может войти в свою критическую секцию.

Команда TAS является примером простой машинной команды, предназначен­ной для реализации блокировки. Подобные команды имеются в большинстве компьютеров. Они могут выполнять и дополнительные функции, такие как ус­ловные переходы на основе результатов проверки.

Соседние файлы в папке Архитектура компьютеров