ПредишенСледващото

Различни видове брави се използват в програмирането за предпазване критична точка код от едновременното изпълнение. Затова се заключва често се използва за защита на части от зоните на код и данни не са, макар че, например, семафори (не бинарни) се използват главно за ограничаване на достъпа до данните.

В тази статия, ние ще започнем обсъждане на различните видове брави, които са налични при програмирането модули на ядрото.

видове брави

До появата и широкото разпространение на SMP, когато физически паралелизъм не съществува, ключалката се използва в класическия начин (както е описано от Е. Dijkstra), защита на критичните зони на програмата от едновременното изпълнение на множество процеси. Такива механизми действат за сметка на заявения процес на преместване в заключено състояние до момента на освобождаването на заявения ресурс. Такива брави ще се наричат ​​пасивни брави, и в този случай, процесорът спира изпълнението на текущия процес на мястото на блокиране и ключове с изпълнението на друг процес (може би празен ход).

А коренно различен вид -active заключване брави - се появи с SMP системи, когато процесора е в очакване на освобождаването на недостъпен ресурс не се превеждат на заключено състояние, и изпълнява празни цикли. В този случай, процесорът е освободен за извършване на друг процес в очакване в системата, и продължава активно да изпълнява ( "празни" цикли) в контекста на текущия път на изпълнение.

Тези два типа брави (всеки от които включва няколко подтипове) са коренно различни в основни параметри:

  • възможността за използване на пасивен заключване (превключвател контекст) може да бъде само част от код, разполага със собствен контекст (писане на задачата), която по-късно можете да се върнете (активност), и да се прекъсне, работещи или Tasklets това условие не е изпълнено;
  • ефективност: активно заключване не винаги се губят в пасивна изпълнението заради превключването на контекст в системата е процес отнема известно време, така че те могат да бъдат дори по-ефективен от пасивно изчакване за кратък период от време активната ключалката.

Семафори (mutexes)

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

Spinlocks позволяват да се задържи заключващото само една задача в даден момент, но броят на задачите за семафор (брой), които имат право да притежават едновременно с това (собствен семафор) може да се настрои при обявяване на променлива в съответното поле на семафор структура:

Ако стойността на брой е по-голям от 1, семафор се нарича броене семафор и позволява на брой нишки, които са едновременно поддържа заключване не е по-голяма от стойността на брояча на употреба (брой). Има ситуации, когато разрешения брой теми, които могат едновременно да държат семафор е равна на 1 (както и за спин-заключване), и се наричат ​​двоични семафори или взаимно изключващи се резета (с мутекс, мутекс, защото гарантира взаимно изключващи достъп - взаимно изключване). Двоични семафори (mutexes) е най-често се използват за осигуряване на взаимно изключителен достъп до кодови фрагменти, наречена критична точка.

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

  1. са заловени мутекс винаги ще бъде едноличен собственик, заловен него;
  2. блокирани мутекси потоци освобождаване (мутекси освобождаване) може да притежава само един мутекс поток.

В случай на броими семафор потоци освобождаване блокирани по семафора може някой от потоците, които притежава семафора.

Статично разделителна способност и инициализиращите семафори изпълняват макроси:

За създаване на взаимно изключващи заключване (мутекс) има по-кратък синтаксис:

- когато, и в двата случая, името - името на променлива от тип семафор.

Но най-вече семафори се създават динамично, като част от по-големите структури от данни. В този случай, за да се инициализира се използва функцията за семафор тотализатор:

Макрос се използва за инициализиране на двоичен семафор (мутекс):

В операционната система Linux, за да улови семафор (мутекс) се използва за определяне на работа (). намалява брояч по един. Ако стойността на брояч е по-голяма или равна на нула, а след това на ключалката беше успешно заловени, а задачата може да влезе в критична секция. Ако стойността на брояч (след спадане) е по-малко от нула, а след това на работното място се поставя в опашката за изчакване и процесора продължава да изпълнява други задачи. до () метод се използва за освобождаване на семафор (след завършване критична точка), неговото изпълнение увеличава брояча на семафор единица, при което един от наличните блокирани потоци може да улови ключалката (основно е, че е невъзможно да се повлияе на начина особено поток брой блокиран е избрано). Изброените по-долу са други операции на семафори.

  • анулира надолу (структура семафор * SEM) - поставя проблема в заключена държавни очаквания TASK_UNINTERRUPTIBLE флаг. В повечето случаи това не е желателно, тъй като един процес, който е в очакване на семафор, няма да реагира на сигналите.
  • вътр down_interruptible (структура семафор * SEM) - се опитва да улови семафора. Ако този опит е неуспешен, тогава проблемът се прехвърля в заключено състояние с TASK_INTERRUPTIBLE флаг (в структурата на задачата). Такова състояние на процеса означава, че работата може да се върне към изпълнението на сигнала, както и такава възможност обикновено е много ценно. Ако сигналът идва в момент, когато задачата е блокиран на семафора, тогава проблемът се връща за извършване и down_interruptible () връща стойност - EINTR.
  • вътр down_trylock (структура семафор * SEM) - се използва за снимане без блокиране на семафор. Ако семафор е вече заключена, функцията веднага се връща ненулева стойност. Ако се окаже успешна, улавяне на семафор се връща към нула и капан за заключване.
  • вътр down_timeout (структура семафор * SEM, дълги мигове) - се използва за да се опита да улови семафор по време на тактове времевия интервал система кърлежи.

Spinlocks

Блокирането на опит да се влезе в критичен участък с помощта на семафор означава потенциален проблем за трансфер в заключено състояние и превключването на контекста, че е скъпа операция. Spinlock (spinlock_t), използван за синхронизация в случаите, когато:

  • Тя не позволява контекст изпълнение ключ в състояние (контекста прекъсване) на блокиране;
  • или трябва да се кратковременно блокиране без превключване на контекста.

Те чакат за освобождаването на активен в празен цикъл. Ако необходимостта от синхронизация е свързано само с наличието на множество процесори в системата, използване на спин-ключалката, на базата на прост цикъл чака малки критични участъци. заключване Spin може да бъде двоичен само. Определения, отнасящи се до spinlock_t. са разпределени в няколко заглавни файлове:

За да нулирате spinlock_t и свързаната тип rwlock_t. което ще бъде обяснено в подробности по-долу, преди (и литература) се използват макроси:

Това означава, че тези макроси не са обявени за поддържани и могат да бъдат отстранени при всяка следваща версия. Следователно, за да се идентифицират и използват нови инициализация макроси (еквивалентни по смисъла на написано по-горе) в следния формат:

Тези макроси са статично определение на отделните променливи на (автономна) spinlock_t тип. И точно като други примитиви, възможност за динамично инициализира, обявена преди променлива (най-често, тази променлива е областта, като част от една по-сложна структура):

Spinlock_t главния интерфейс съдържа няколко обаждания, за да улавят и освободите заключването:

Ако компилирате ядрото не е била активирана от ОМП (многопроцесорни) и кодът не е конфигуриран ядрото присвояване (задължително и двете условия), за spinlock_t не се компилира (и на тяхно място ще остане празно пространство) поради Препроцесор директиви условията компилация.

Забележка. За разлика от внедряванията в някои други операционни системи, на спин-ключалката на операционната система Linux не е рекурсивно. Това означава, че кодът показани по-долу, автоматично ще доведе до ситуация на безизходица (процесора ще изпълни безкрайно и фрагмента ще настъпи влошаване на системата, тъй като броя на процесорите, налични в системата се намалява):

Рекурсивно улавяне spinlock косвено може да се случи в прекъсне треньор, така че да обхване като блокиране, трябва да деактивирате прекъсвания на местната процесор. Това е най-общия случай, следователно, специален интерфейс е предвиден за него:

За spinlock определено предизвикателства, като например:

  • вътр spin_try_lock (spinlock_t * SL) - опит да се улови, без да блокира, ако мутекс вече е заключена, функцията връща ненулева стойност;
  • вътр spin_is_locked (spinlock_t * SL) - връща ненулева стойност, ако в момента е заключен от.

за четене и запис за заключване

Особено, но чести, синхронизация сценарий са "за четене и запис". "Читателите" четат само състояние на някои ресурси, и следователно може да има съвместна едновременен достъп до него. "Писатели" промяна на състоянието на ресурса, и така писателят трябва да имат изключителен достъп до ресурса, а ресурсите четене за всички читатели в този момент, както и да бъдат блокирани. За изпълнение на четене и запис ключалки в ядрото на Линукс, има отделни версии на семафори и центрофуги ключалки. в реално време mutexes не са изпълнение, подходящ за използване в този сценарий.

Забележка. Обръщаме внимание на факта, че точно същата функционалност може да се постигне чрез използване на класически примитиви за синхронизация (мутекс или спин заключване), като просто хванете критична точка, независимо от вида на предстоящата операция. за четене и запис за заключване, наложена от съображения за ефективност на реализация на сценария за масата на такова използване.

За семафор вместо структура семафор структура се въвежда структура rw_semaphore структура. и набор от интерфейсни функции за заснемане / освобождаване (обикновен надолу () / нагоре ()), се удължава до:

  • down_read ( rwsem) - опитвайки се да привлекат семафор за четене;
  • up_read ( rwsem - освобождаването на семафор за четене;
  • down_write ( rwsem) - се опита да улови семафор за запис;
  • up_write ( rwsem) - освобождаването на семафор за запис;

Семантиката на тези операции е както следва:

  • Ако семафор не е заловен, всяко улавяне (down_read () или down_write ()) ще бъде успешен (без блокиране);
  • ако семафор вече заловени за четене. последващ опит да улови семафор за четене (down_read ()), ще завърши успешно (без опасност от блокиране), но такова искане да улови семафор за запис (down_write ()) блокиране край;
  • ако семафор вече заловени за протокола. След това всеки следващ опит за улавяне на семафора (down_read () или down_write ()) блокиране край;

Статично определено за четене и запис семафор е създадена от макро:

Семафори четат записи, които са динамично създаден, трябва да се инициализира с функцията:

Забележка. От описанието на инициализация може да се види, че за четене и запис семафори са двоични само (без своевременно се използва), т.е. (в Linux терминология) всъщност не е семафор и мутекс.

По-долу е пример за това как да се чете и запис семафори може да се използва по време на работа (актуализиране и четене) кръглите списъците Linux (че ние говорихме по-рано):

По същия начин, както се прави за семафор се въвежда и за четене и запис за заключване за spinlock:

С поредица от операции:

Забележка. Ако компилирате ядрото не е установена и не ОМП конфигурира ядрото присвояване код, а след това spinlock_t не се компилира (на тяхно място ще останат празни пространства), и следователно съответната rwlock_t.

Също така, заключване, заловени за четене, не може да бъде допълнително увеличен, за да заключите заловен да рекорд.:

Тази последователност осигурява оператори поява безизходица, тъй като на периодичната проверка ще се извършва при превземането на заключване на запис, докато всички нишки, които улавят ключалката за четене, не е освободена, тя се отнася за текущия поток, което не е в състояние да направи това някога.

Но четене няколко теми, може спокойно да уловите същия ключалката за четене и запис, така че една нишка може да бъде безопасно рекурсивно да улови една и съща ключалката, за да прочетете няколко пъти, например в прекъсващ оператор, без да деактивирате прекъсва.

заключение

По време на четене и запис с въвеждането им на свързана заключващ механизъм за подобряване на значителна производителност, и те причиняват значително ентусиазъм на разработчиците. Но последвалото опитът показва, че този механизъм е присъщо скрита опасност, че при високи и единни повиквания четене плътност, искането да се промени (запис) структура на запис може да се забави в продължение на безкрайно дълги интервали от време. За тази функция, трябва да се помни, когато се оценява възможността за използване на този механизъм в кода си. Частично намаляване на това ограничение се опитва да заключите следните под - сериен ключалката, която ще обсъдим в следващата статия.

Вземете продукти и технологии

  • Тест софтуер от IBM софтуер. Изтеглете пробна версия, използвайте онлайн демо версия, използвайте продукта в тестова среда или среда на облак. Предлага се за вас да проучи повече от 100 продукти от IBM.

Свързани статии

Подкрепете проекта - споделете линка, благодаря!