Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Лекция №7. При ассемблировании возможно незапланированное переключение контекста:




 

При ассемблировании возможно незапланированное переключение контекста:

 

Thr1 Thr2

 
 


MOV EAX, [g_x]

ADD EAX, 1

MOV [g_x], EAX

 

Из-за “расщепления” команды inc возможно возникновение “условия гонки” (race condition). Нужно, чтобы эти три ассемблерные команды выполнялись как единое целое.

Для того, чтобы достичь неделимости арифметических операций в WinAPI имеется функция Interlock.

 

DWORD WinAPI Thr1(PVOID) {

InterlockExchangeAdd (&g_x, 1);

return 0;

}

 

Эта функция и другие функции семейства Interlock работают в пользовательском режиме.

Варианты реализаций:

  1. Блокирование прерываний;
  2. Блокирование шины;
  3. В системе команд используется специальная инструкция TestAndSetLock (TSL), при помощи которой можно реализовать обобщенную критическую секцию.

 

enter: TSL Reg, [Lock]

CMP Reg, #0;;0 значит, что текущий поток выполнил блокировку

JNE enter;и ему можно войти в критическую секцию

RET

leave: MOV [Lock], #0

RET

 

TSL неразрывным образом изменяет значение по адресу Lock на ненулевое число, при этом в регистр помещается старое значение. Такой метод называется Спин-Блокировка.

Еще один вариант Спин-Блокировки:

 

BOOL g_ResInUse = FALSE;

вход: while (InterlockedExchange(&g_ResInUse, TRUE) = = TRUE) sleep(0);

выход: InterlockedExchange(&g_ResInUse, FALSE);

 

Эти протоколы входа/выхода присваивают значение, переданное во втором параметре InterlockedExchange(), переменной, адрес которой указан в первом, и возвращают значение до модификации.

 

PVOID InterlockedExchangePointer(PVOID * pvTarget, PVOID * pvValue);

Long InterlockedComparePointer(PLONG plDest, LONG lExchange, Long

lComparand)

 

Алгоритм Петерсона для Спин-Блокировки

Peterson, 1981г.

Алгоритм разрыва узла через обмен через файлы.

 

white (True) {

< протокол входа //enter() >;

< вход в критической секции >;

< протокол выхода //leave() >;

< код вне критической секции >;

}

 

Для обеспечения работоспособности требуется выполнение 4-х условий:

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

 

Проанализируем это:

int lock = 0

void enter() {

while (lock!= 0) /*ждем*/;

lock = 1;

}

void leave() { lock = 0; }

 

Гарантируют ли такие протоколы условия взаимного исключения? Нет. Введем переменную, которая определяет, чья очередь входа в критическую секцию.

 

int turn = 0;

while (TRUE) { -//-

while (turn!= 0) /*ждем*/; while (turn!= 1) -//-

< критическая секция > -//-

turn = 1; turn = 0;

< вне критической секции >; -//-

} -//-

 

Этим способом обеспечивается условие взаимного исключения (1 условие). Не выполняется 3 условие: застряв вне критической секции, процесс 0 блокирует процесс 1.

 

int turn = 0;

int interested[2] = { FALSE, FALSE };

 

void enter(int process) {

int other = 1–process;

interested[process] = TRUE;

turn = process;

while (turn = = process && interested[other] = = TRUE) /*ждем*/;

}

void leave(int process) { interested [process] = FALSE; }

 

Этот способ обеспечивает соблюдение всех условий.

Идея алгоритма:

  1. модификацию условий нужно выполнять до проверки, а не после;
  2. для каждого из процессов нужно завести по флагу (массив Interested[]); ненулевое значение флага свидетельствует о том, что соответствующий процесс готов войти в критический участок, поэтому каждый из процессов перед входом в критический участок должен выполнять проверку while (Interested = = TRUE) и ждать;
  3. если два процесса одновременно начинают выполнять проверку, то возникает тупик. Для разрешения тупика («разрыва узла») вводится вспомогательная переменная turn, которая в случае конфликта разрешает ввод в критическую секцию только одному процессу.

 

Так же известен алгоритм Lamport.

 




Поделиться с друзьями:


Дата добавления: 2014-12-07; Просмотров: 349; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.012 сек.