Как использовать TestAndSet() для решения проблемы критической секции?
Я готовлюсь к экзамену и испытываю трудности с концепцией. Это псевдокод, который мне дают:
int mutex = 0;
do {
while (TestAndSet(&mutex));
// critical section
mutiex = 0;
// remainder section
} while (TRUE);
Мой инструктор говорит, что с этим кодом встречаются только два из трех необходимых условий (взаимное исключение, прогресс и ограниченное ожидание), но я не понимаю, какое из них не выполняется...??
Как следует изменить код для поддержки отсутствующего условия для решения проблемы критической области? Заранее спасибо за любую информацию!
4 ответа
Если кто-то видит это в поиске ответа, приведенный выше код не поддерживает ограниченное ожидание (должно быть ограничение на количество времени, которое процесс должен ждать). Это правильный код, обеспечивающий выполнение всех трех условий для обеспечения синхронизации с помощью SetAndTest:
do{
waiting[i] = TRUE;
key = TRUE;
while(waiting[i] && key)
key = TestAndSet(&lock);
waiting[i] = FALSE;
// Critical Section
j = (i + 1) % n;
while ((j != i) && !waiting[j])
j = (j+1) % n;
if (j == i )
lock = FALSE;
else
waiting[j] = FALSE;
// Remainder Section
} while (TRUE);
Прежде всего, хороший небольшой пример, но testandset принимает логические аргументы, и по умолчанию mutex имеет значение FALSE
, Так int mutex=0
на самом деле boolean mutex=FALSE
Приведенный выше код имеет взаимное исключение и прогресс, но не ограниченное ожидание. Также ваше определение testandset
неправильно. Так должно быть target=TRUE
и не target=TRUE
,
Ограниченное ожидание здесь не встречается. Вы можете видеть, что должно быть определено, сколько раз конкретный процесс может перейти в критическую секцию, чтобы избежать голодания других процессов... и должно быть ограничение на время, в течение которого процесс должен ждать
Это потому, что мьютекс должен быть установлен с использованием атомарных команд LOAD и STORE, чтобы доступ к памяти не переупорядочивался? Атомарное выполнение набора инструкций означает, что инструкции обрабатываются как один шаг, который не может быть прерван.
// example process using mutual exclusion
void process() {
int mutex;
init_lock (&mutex);
do {
lock (&mutex);
// critical section
unlock (&mutex);
//remainder section
} while(TRUE);
}
// mutual exclusion functions
void init_lock (int *mutex) {
*mutex = 0;
}
void lock (int *mutex) {
while(TestAndSet(mutex))
}
void unlock (int *mutex) {
*mutex = 0;
}
int TestAndSet(*target) {
int rv = *target;
*target = 1;
return rv;
}
Глядя на это, кажется, что функции делают то же самое, что и пример кода, опубликованный ранее, но я предполагаю, что этот способ гарантирует взаимное исключение, потому что функции, работающие на * target, являются атомарными...
Извините за любые опечатки...